Merge pull request #5237 from vostrnad/p2tr-without-witness

Fix errors caused by P2TR inputs without witness data
This commit is contained in:
softsimon 2024-07-01 10:48:16 +09:00 committed by GitHub
commit 8fc5fdbde6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 35 additions and 29 deletions

View File

@ -460,11 +460,10 @@ export class Common {
case 'v0_p2wpkh': flags |= TransactionFlags.p2wpkh; break; case 'v0_p2wpkh': flags |= TransactionFlags.p2wpkh; break;
case 'v0_p2wsh': flags |= TransactionFlags.p2wsh; break; case 'v0_p2wsh': flags |= TransactionFlags.p2wsh; break;
case 'v1_p2tr': { case 'v1_p2tr': {
if (!vin.witness?.length) {
throw new Error('Taproot input missing witness data');
}
flags |= TransactionFlags.p2tr; flags |= TransactionFlags.p2tr;
if (vin.witness?.length) {
flags = Common.isInscription(vin, flags); flags = Common.isInscription(vin, flags);
}
} break; } break;
} }
} else { } else {

View File

@ -71,6 +71,10 @@ export function calcSegwitFeeGains(tx: Transaction) {
} }
if (isP2tr) { if (isP2tr) {
// every valid taproot input has at least one witness item, however transactions
// created before taproot activation don't need to have any witness data
// (see https://mempool.space/tx/b10c007c60e14f9d087e0291d4d0c7869697c6681d979c6639dbd960792b4d41)
if (vin.witness?.length) {
if (vin.witness.length === 1) { if (vin.witness.length === 1) {
// key path spend // key path spend
// we don't know if this was a multisig or single sig (the goal of taproot :)), // we don't know if this was a multisig or single sig (the goal of taproot :)),
@ -85,6 +89,7 @@ export function calcSegwitFeeGains(tx: Transaction) {
// but only assumptions can be made because the scripts themselves are unknown (again, the goal of taproot :)) // but only assumptions can be made because the scripts themselves are unknown (again, the goal of taproot :))
// TODO maybe add some complex scripts that are specified somewhere, so that size is known, such as lightning scripts // TODO maybe add some complex scripts that are specified somewhere, so that size is known, such as lightning scripts
} }
}
} else { } else {
const script = isP2shP2Wsh || isP2wsh ? vin.inner_witnessscript_asm : vin.inner_redeemscript_asm; const script = isP2shP2Wsh || isP2wsh ? vin.inner_witnessscript_asm : vin.inner_redeemscript_asm;
let replacementSize: number; let replacementSize: number;

View File

@ -335,10 +335,11 @@ export function getTransactionFlags(tx: Transaction, cpfpInfo?: CpfpInfo, replac
case 'v0_p2wpkh': flags |= TransactionFlags.p2wpkh; break; case 'v0_p2wpkh': flags |= TransactionFlags.p2wpkh; break;
case 'v0_p2wsh': flags |= TransactionFlags.p2wsh; break; case 'v0_p2wsh': flags |= TransactionFlags.p2wsh; break;
case 'v1_p2tr': { case 'v1_p2tr': {
if (!vin.witness?.length) {
throw new Error('Taproot input missing witness data');
}
flags |= TransactionFlags.p2tr; flags |= TransactionFlags.p2tr;
// every valid taproot input has at least one witness item, however transactions
// created before taproot activation don't need to have any witness data
// (see https://mempool.space/tx/b10c007c60e14f9d087e0291d4d0c7869697c6681d979c6639dbd960792b4d41)
if (vin.witness?.length) {
// in taproot, if the last witness item begins with 0x50, it's an annex // in taproot, if the last witness item begins with 0x50, it's an annex
const hasAnnex = vin.witness?.[vin.witness.length - 1].startsWith('50'); const hasAnnex = vin.witness?.[vin.witness.length - 1].startsWith('50');
// script spends have more than one witness item, not counting the annex (if present) // script spends have more than one witness item, not counting the annex (if present)
@ -350,6 +351,7 @@ export function getTransactionFlags(tx: Transaction, cpfpInfo?: CpfpInfo, replac
flags |= TransactionFlags.inscription; flags |= TransactionFlags.inscription;
} }
} }
}
} break; } break;
} }