Merge pull request #4258 from mempool/mononaut/esplora-sigops
Sigops everywhere
This commit is contained in:
commit
12b49abfdd
@ -251,7 +251,7 @@ class BitcoinRoutes {
|
||||
|
||||
private async getTransaction(req: Request, res: Response) {
|
||||
try {
|
||||
const transaction = await transactionUtils.$getTransactionExtended(req.params.txId, true);
|
||||
const transaction = await transactionUtils.$getTransactionExtended(req.params.txId, true, false, false, true);
|
||||
res.json(transaction);
|
||||
} catch (e) {
|
||||
let statusCode = 500;
|
||||
|
@ -6,6 +6,7 @@ export namespace IEsploraApi {
|
||||
size: number;
|
||||
weight: number;
|
||||
fee: number;
|
||||
sigops?: number;
|
||||
vin: Vin[];
|
||||
vout: Vout[];
|
||||
status: Status;
|
||||
|
@ -94,7 +94,7 @@ class Mempool {
|
||||
logger.debug(`Migrating ${Object.keys(this.mempoolCache).length} transactions from disk cache to Redis cache`);
|
||||
}
|
||||
for (const txid of Object.keys(this.mempoolCache)) {
|
||||
if (!this.mempoolCache[txid].sigops || this.mempoolCache[txid].effectiveFeePerVsize == null) {
|
||||
if (!this.mempoolCache[txid].adjustedVsize || this.mempoolCache[txid].sigops == null || this.mempoolCache[txid].effectiveFeePerVsize == null) {
|
||||
this.mempoolCache[txid] = transactionUtils.extendMempoolTransaction(this.mempoolCache[txid]);
|
||||
}
|
||||
if (this.mempoolCache[txid].order == null) {
|
||||
|
@ -116,7 +116,7 @@ class TransactionUtils {
|
||||
public extendMempoolTransaction(transaction: IEsploraApi.Transaction): MempoolTransactionExtended {
|
||||
const vsize = Math.ceil(transaction.weight / 4);
|
||||
const fractionalVsize = (transaction.weight / 4);
|
||||
const sigops = !Common.isLiquid() ? this.countSigops(transaction) : 0;
|
||||
let sigops = Common.isLiquid() ? 0 : (transaction.sigops != null ? transaction.sigops : this.countSigops(transaction));
|
||||
// https://github.com/bitcoin/bitcoin/blob/e9262ea32a6e1d364fb7974844fadc36f931f8c6/src/policy/policy.cpp#L295-L298
|
||||
const adjustedVsize = Math.max(fractionalVsize, sigops * 5); // adjusted vsize = Max(weight, sigops * bytes_per_sigop) / witness_scale_factor
|
||||
const feePerVbytes = (transaction.fee || 0) / fractionalVsize;
|
||||
@ -155,7 +155,7 @@ class TransactionUtils {
|
||||
sigops += 20 * (script.match(/OP_CHECKMULTISIG/g)?.length || 0);
|
||||
} else {
|
||||
// in redeem scripts and witnesses, worth N if preceded by OP_N, 20 otherwise
|
||||
const matches = script.matchAll(/(?:OP_(\d+))? OP_CHECKMULTISIG/g);
|
||||
const matches = script.matchAll(/(?:OP_(?:PUSHNUM_)?(\d+))? OP_CHECKMULTISIG/g);
|
||||
for (const match of matches) {
|
||||
const n = parseInt(match[1]);
|
||||
if (Number.isInteger(n)) {
|
||||
@ -189,6 +189,12 @@ class TransactionUtils {
|
||||
sigops += this.countScriptSigops(bitcoinjs.script.toASM(Buffer.from(input.witness[input.witness.length - 1], 'hex')), false, true);
|
||||
}
|
||||
break;
|
||||
|
||||
case input.prevout.scriptpubkey_type === 'p2sh':
|
||||
if (input.inner_redeemscript_asm) {
|
||||
sigops += this.countScriptSigops(input.inner_redeemscript_asm);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -292,9 +292,9 @@
|
||||
<td i18n="transaction.vsize|Transaction Virtual Size">Virtual size</td>
|
||||
<td [innerHTML]="'‎' + (tx.weight / 4 | vbytes: 2)"></td>
|
||||
</tr>
|
||||
<tr *ngIf="cpfpInfo && cpfpInfo.adjustedVsize && cpfpInfo.adjustedVsize > (tx.weight / 4)">
|
||||
<tr *ngIf="adjustedVsize != null">
|
||||
<td i18n="transaction.adjusted-vsize|Transaction Adjusted VSize">Adjusted vsize</td>
|
||||
<td [innerHTML]="'‎' + (cpfpInfo.adjustedVsize | vbytes: 2)"></td>
|
||||
<td [innerHTML]="'‎' + (adjustedVsize | vbytes: 2)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td i18n="block.weight">Weight</td>
|
||||
@ -314,9 +314,9 @@
|
||||
<td i18n="transaction.locktime">Locktime</td>
|
||||
<td [innerHTML]="'‎' + (tx.locktime | number)"></td>
|
||||
</tr>
|
||||
<tr *ngIf="cpfpInfo && cpfpInfo.adjustedVsize && cpfpInfo.adjustedVsize > (tx.weight / 4)">
|
||||
<tr *ngIf="sigops != null">
|
||||
<td i18n="transaction.sigops|Transaction Sigops">Sigops</td>
|
||||
<td [innerHTML]="'‎' + (cpfpInfo.sigops | number)"></td>
|
||||
<td [innerHTML]="'‎' + (sigops | number)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td i18n="transaction.hex">Transaction hex</td>
|
||||
|
@ -62,6 +62,8 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
rbfReplaces: string[];
|
||||
rbfInfo: RbfTree;
|
||||
cpfpInfo: CpfpInfo | null;
|
||||
sigops: number | null;
|
||||
adjustedVsize: number | null;
|
||||
showCpfpDetails = false;
|
||||
fetchCpfp$ = new Subject<string>();
|
||||
fetchRbfHistory$ = new Subject<string>();
|
||||
@ -343,6 +345,10 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
if (tx.fee === undefined) {
|
||||
this.tx.fee = 0;
|
||||
}
|
||||
if (this.tx.sigops != null) {
|
||||
this.sigops = this.tx.sigops;
|
||||
this.adjustedVsize = Math.max(this.tx.weight / 4, this.sigops * 5);
|
||||
}
|
||||
this.tx.feePerVsize = tx.fee / (tx.weight / 4);
|
||||
this.isLoadingTx = false;
|
||||
this.error = undefined;
|
||||
@ -543,6 +549,10 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
}
|
||||
|
||||
this.cpfpInfo = cpfpInfo;
|
||||
if (this.cpfpInfo.adjustedVsize && this.cpfpInfo.sigops != null) {
|
||||
this.sigops = this.cpfpInfo.sigops;
|
||||
this.adjustedVsize = this.cpfpInfo.adjustedVsize;
|
||||
}
|
||||
this.hasEffectiveFeeRate = hasRelatives || (this.tx.effectiveFeePerVsize && (Math.abs(this.tx.effectiveFeePerVsize - this.tx.feePerVsize) > 0.01));
|
||||
}
|
||||
|
||||
@ -569,6 +579,8 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
this.replaced = false;
|
||||
this.transactionTime = -1;
|
||||
this.cpfpInfo = null;
|
||||
this.adjustedVsize = null;
|
||||
this.sigops = null;
|
||||
this.hasEffectiveFeeRate = false;
|
||||
this.rbfInfo = null;
|
||||
this.rbfReplaces = [];
|
||||
|
@ -26,6 +26,7 @@ export interface Transaction {
|
||||
_outspends?: Outspend[];
|
||||
_channels?: TransactionChannels;
|
||||
price?: Price;
|
||||
sigops?: number;
|
||||
}
|
||||
|
||||
export interface TransactionChannels {
|
||||
|
Loading…
x
Reference in New Issue
Block a user