mirror of
https://github.com/mempool/mempool.git
synced 2026-08-13 12:33:11 +02:00
[Refactor] Unify CLTV decode fn.
This commit is contained in:
parent
de0ddf1b5e
commit
792c5d7509
3 changed files with 47 additions and 56 deletions
|
|
@ -1,5 +1,6 @@
|
|||
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, SimpleChanges } from '@angular/core';
|
||||
import { SigInfo, SighashLabels } from '@app/shared/transaction.utils';
|
||||
import { detectCltvTimestamps, formatCltvTimestamp } from '@app/shared/script.utils';
|
||||
|
||||
@Component({
|
||||
selector: 'app-asm',
|
||||
|
|
@ -39,25 +40,7 @@ export class AsmComponent {
|
|||
parseASM(): void {
|
||||
const allInstructions = this.asm.split('OP_').filter(instruction => instruction.trim() !== '');
|
||||
|
||||
const cltvTimestamps: Map<number, number> = new Map();
|
||||
allInstructions.forEach((instruction, index, arr) => {
|
||||
const parts = instruction.split(' ');
|
||||
const instructionName = parts[0];
|
||||
const args = parts.slice(1);
|
||||
|
||||
if (instructionName === 'PUSHBYTES_4' && args.length > 0 && args[0].length === 8 && /^[0-9a-fA-F]+$/.test(args[0])) {
|
||||
if (index + 1 < arr.length) {
|
||||
const nextInstruction = arr[index + 1].split(' ')[0];
|
||||
if (nextInstruction === 'CLTV') {
|
||||
const bytes = args[0].match(/.{2}/g) || [];
|
||||
const littleEndianValue = bytes.reverse().join('');
|
||||
const timestamp = parseInt(littleEndianValue, 16);
|
||||
cltvTimestamps.set(index, timestamp);
|
||||
cltvTimestamps.set(index + 1, timestamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
const cltvTimestamps = detectCltvTimestamps(allInstructions);
|
||||
|
||||
let instructions = allInstructions;
|
||||
if (this.crop && this.asm.length > this.crop) {
|
||||
|
|
@ -110,14 +93,7 @@ export class AsmComponent {
|
|||
}
|
||||
|
||||
formatTimestamp(timestamp: number): string {
|
||||
if (timestamp < 500000000) {
|
||||
return `Block height: ${timestamp}`;
|
||||
}
|
||||
if (timestamp > 4294967295) {
|
||||
return `Invalid timestamp: ${timestamp}`;
|
||||
}
|
||||
const date = new Date(timestamp * 1000);
|
||||
return date.toISOString().replace('T', ' ').replace(/\.\d{3}Z$/, ' UTC');
|
||||
return formatCltvTimestamp(timestamp);
|
||||
}
|
||||
|
||||
readonly opcodeStyles: Map<string, string> = new Map([
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { detectCltvTimestamps, formatCltvTimestamp } from '@app/shared/script.utils';
|
||||
|
||||
@Pipe({
|
||||
name: 'asmStyler',
|
||||
|
|
@ -11,27 +12,7 @@ export class AsmStylerPipe implements PipeTransform {
|
|||
let out = '';
|
||||
let chars = -3;
|
||||
|
||||
// First pass: find CLTV timestamps
|
||||
const cltvTimestamps: Map<number, number> = new Map();
|
||||
for (let i = 0; i < instructions.length; i++) {
|
||||
const instruction = instructions[i];
|
||||
const parts = instruction.split(' ');
|
||||
const opcode = parts[0];
|
||||
const args = parts.slice(1);
|
||||
|
||||
if (opcode === 'PUSHBYTES_4' && args.length > 0 && args[0].length === 8 && /^[0-9a-fA-F]+$/.test(args[0])) {
|
||||
if (i + 1 < instructions.length) {
|
||||
const nextOpcode = instructions[i + 1].split(' ')[0];
|
||||
if (nextOpcode === 'CLTV') {
|
||||
const bytes = args[0].match(/.{2}/g) || [];
|
||||
const littleEndianValue = bytes.reverse().join('');
|
||||
const timestamp = parseInt(littleEndianValue, 16);
|
||||
cltvTimestamps.set(i, timestamp);
|
||||
cltvTimestamps.set(i + 1, timestamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const cltvTimestamps = detectCltvTimestamps(instructions);
|
||||
|
||||
for (let i = 0; i < instructions.length; i++) {
|
||||
const instruction = instructions[i];
|
||||
|
|
@ -349,14 +330,7 @@ export class AsmStylerPipe implements PipeTransform {
|
|||
}
|
||||
|
||||
formatTimestamp(timestamp: number): string {
|
||||
if (timestamp < 500000000) {
|
||||
return `Block height: ${timestamp}`;
|
||||
}
|
||||
if (timestamp > 4294967295) {
|
||||
return `Invalid timestamp: ${timestamp}`;
|
||||
}
|
||||
const date = new Date(timestamp * 1000);
|
||||
return date.toISOString().replace('T', ' ').replace(/\.\d{3}Z$/, ' UTC');
|
||||
return formatCltvTimestamp(timestamp);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -555,4 +555,45 @@ export function isPoint(pointHex: string): boolean {
|
|||
// If we square and it's equal, then it was a perfect root and valid point.
|
||||
return (y * y) % curveP === ySquared;
|
||||
}
|
||||
}
|
||||
|
||||
export function detectCltvTimestamps(instructions: string[]): Map<number, number> {
|
||||
const cltvTimestamps: Map<number, number> = new Map();
|
||||
for (let i = 0; i < instructions.length; i++) {
|
||||
const instruction = instructions[i];
|
||||
const parts = instruction.split(' ');
|
||||
const opcode = parts[0];
|
||||
const args = parts.slice(1);
|
||||
|
||||
const pushMatch = opcode.match(/^PUSHBYTES_([1-4])$/);
|
||||
if (pushMatch && args.length > 0) {
|
||||
const byteCount = parseInt(pushMatch[1], 10);
|
||||
const expectedLength = byteCount * 2;
|
||||
|
||||
if (args[0].length === expectedLength && /^[0-9a-fA-F]+$/.test(args[0])) {
|
||||
if (i + 1 < instructions.length) {
|
||||
const nextOpcode = instructions[i + 1].split(' ')[0];
|
||||
if (nextOpcode === 'CLTV') {
|
||||
const bytes = args[0].match(/.{2}/g) || [];
|
||||
const littleEndianValue = bytes.reverse().join('');
|
||||
const timestamp = parseInt(littleEndianValue, 16);
|
||||
cltvTimestamps.set(i, timestamp);
|
||||
cltvTimestamps.set(i + 1, timestamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return cltvTimestamps;
|
||||
}
|
||||
|
||||
export function formatCltvTimestamp(timestamp: number): string {
|
||||
if (timestamp < 500000000) {
|
||||
return `Block height: ${timestamp}`;
|
||||
}
|
||||
if (timestamp > 4294967295) {
|
||||
return `Invalid timestamp: ${timestamp}`;
|
||||
}
|
||||
const date = new Date(timestamp * 1000);
|
||||
return date.toISOString().replace('T', ' ').replace(/\.\d{3}Z$/, ' UTC');
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue