Merge branch 'master' into run_tests_on_merge

This commit is contained in:
Felipe Knorr Kuhn 2023-02-28 20:09:30 -08:00 committed by GitHub
commit 1d5e4aa410
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 3569 additions and 1595 deletions

View File

@ -237,14 +237,21 @@ export class Common {
].join('x'); ].join('x');
} }
static utcDateToMysql(date?: number): string { static utcDateToMysql(date?: number | null): string | null {
if (date === null) {
return null;
}
const d = new Date((date || 0) * 1000); const d = new Date((date || 0) * 1000);
return d.toISOString().split('T')[0] + ' ' + d.toTimeString().split(' ')[0]; return d.toISOString().split('T')[0] + ' ' + d.toTimeString().split(' ')[0];
} }
static findSocketNetwork(addr: string): {network: string | null, url: string} { static findSocketNetwork(addr: string): {network: string | null, url: string} {
let network: string | null = null; let network: string | null = null;
let url = addr.split('://')[1]; let url: string = addr;
if (config.LIGHTNING.BACKEND === 'cln') {
url = addr.split('://')[1];
}
if (!url) { if (!url) {
return { return {
@ -261,7 +268,7 @@ export class Common {
} }
} else if (addr.indexOf('i2p') !== -1) { } else if (addr.indexOf('i2p') !== -1) {
network = 'i2p'; network = 'i2p';
} else if (addr.indexOf('ipv4') !== -1) { } else if (addr.indexOf('ipv4') !== -1 || (config.LIGHTNING.BACKEND === 'lnd' && isIP(url.split(':')[0]) === 4)) {
const ipv = isIP(url.split(':')[0]); const ipv = isIP(url.split(':')[0]);
if (ipv === 4) { if (ipv === 4) {
network = 'ipv4'; network = 'ipv4';
@ -271,7 +278,7 @@ export class Common {
url: addr, url: addr,
}; };
} }
} else if (addr.indexOf('ipv6') !== -1) { } else if (addr.indexOf('ipv6') !== -1 || (config.LIGHTNING.BACKEND === 'lnd' && url.indexOf(']:'))) {
url = url.split('[')[1].split(']')[0]; url = url.split('[')[1].split(']')[0];
const ipv = isIP(url); const ipv = isIP(url);
if (ipv === 6) { if (ipv === 6) {

View File

@ -7,7 +7,7 @@ import cpfpRepository from '../repositories/CpfpRepository';
import { RowDataPacket } from 'mysql2'; import { RowDataPacket } from 'mysql2';
class DatabaseMigration { class DatabaseMigration {
private static currentVersion = 56; private static currentVersion = 57;
private queryTimeout = 3600_000; private queryTimeout = 3600_000;
private statisticsAddedIndexed = false; private statisticsAddedIndexed = false;
private uniqueLogs: string[] = []; private uniqueLogs: string[] = [];
@ -500,6 +500,11 @@ class DatabaseMigration {
this.uniqueLog(logger.notice, '`pools` table has been truncated`'); this.uniqueLog(logger.notice, '`pools` table has been truncated`');
await this.updateToSchemaVersion(56); await this.updateToSchemaVersion(56);
} }
if (databaseSchemaVersion < 57) {
await this.$executeQuery(`ALTER TABLE nodes MODIFY updated_at datetime NULL`);
await this.updateToSchemaVersion(57);
}
} }
/** /**

View File

@ -559,6 +559,17 @@ class ChannelsApi {
const policy1: Partial<ILightningApi.RoutingPolicy> = channel.node1_policy || {}; const policy1: Partial<ILightningApi.RoutingPolicy> = channel.node1_policy || {};
const policy2: Partial<ILightningApi.RoutingPolicy> = channel.node2_policy || {}; const policy2: Partial<ILightningApi.RoutingPolicy> = channel.node2_policy || {};
// https://github.com/mempool/mempool/issues/3006
if ((channel.last_update ?? 0) < 1514736061) { // January 1st 2018
channel.last_update = null;
}
if ((policy1.last_update ?? 0) < 1514736061) { // January 1st 2018
policy1.last_update = null;
}
if ((policy2.last_update ?? 0) < 1514736061) { // January 1st 2018
policy2.last_update = null;
}
const query = `INSERT INTO channels const query = `INSERT INTO channels
( (
id, id,

View File

@ -630,6 +630,11 @@ class NodesApi {
*/ */
public async $saveNode(node: ILightningApi.Node): Promise<void> { public async $saveNode(node: ILightningApi.Node): Promise<void> {
try { try {
// https://github.com/mempool/mempool/issues/3006
if ((node.last_update ?? 0) < 1514736061) { // January 1st 2018
node.last_update = null;
}
const sockets = (node.addresses?.map(a => a.addr).join(',')) ?? ''; const sockets = (node.addresses?.map(a => a.addr).join(',')) ?? '';
const query = `INSERT INTO nodes( const query = `INSERT INTO nodes(
public_key, public_key,

View File

@ -21,7 +21,7 @@ export namespace ILightningApi {
export interface Channel { export interface Channel {
channel_id: string; channel_id: string;
chan_point: string; chan_point: string;
last_update: number; last_update: number | null;
node1_pub: string; node1_pub: string;
node2_pub: string; node2_pub: string;
capacity: string; capacity: string;
@ -36,11 +36,11 @@ export namespace ILightningApi {
fee_rate_milli_msat: string; fee_rate_milli_msat: string;
disabled: boolean; disabled: boolean;
max_htlc_msat: string; max_htlc_msat: string;
last_update: number; last_update: number | null;
} }
export interface Node { export interface Node {
last_update: number; last_update: number | null;
pub_key: string; pub_key: string;
alias: string; alias: string;
addresses: { addresses: {

View File

@ -36,7 +36,6 @@ import bitcoinRoutes from './api/bitcoin/bitcoin.routes';
import fundingTxFetcher from './tasks/lightning/sync-tasks/funding-tx-fetcher'; import fundingTxFetcher from './tasks/lightning/sync-tasks/funding-tx-fetcher';
import forensicsService from './tasks/lightning/forensics.service'; import forensicsService from './tasks/lightning/forensics.service';
import priceUpdater from './tasks/price-updater'; import priceUpdater from './tasks/price-updater';
import mining from './api/mining/mining';
import chainTips from './api/chain-tips'; import chainTips from './api/chain-tips';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';

View File

@ -16,6 +16,9 @@ class BlocksRepository {
* Save indexed block data in the database * Save indexed block data in the database
*/ */
public async $saveBlockInDatabase(block: BlockExtended) { public async $saveBlockInDatabase(block: BlockExtended) {
const truncatedCoinbaseSignature = block?.extras?.coinbaseSignature?.substring(0, 500);
const truncatedCoinbaseSignatureAscii = block?.extras?.coinbaseSignatureAscii?.substring(0, 500);
try { try {
const query = `INSERT INTO blocks( const query = `INSERT INTO blocks(
height, hash, blockTimestamp, size, height, hash, blockTimestamp, size,
@ -65,7 +68,7 @@ class BlocksRepository {
block.extras.medianTimestamp, block.extras.medianTimestamp,
block.extras.header, block.extras.header,
block.extras.coinbaseAddress, block.extras.coinbaseAddress,
block.extras.coinbaseSignature, truncatedCoinbaseSignature,
block.extras.utxoSetSize, block.extras.utxoSetSize,
block.extras.utxoSetChange, block.extras.utxoSetChange,
block.extras.avgTxSize, block.extras.avgTxSize,
@ -78,7 +81,7 @@ class BlocksRepository {
block.extras.segwitTotalSize, block.extras.segwitTotalSize,
block.extras.segwitTotalWeight, block.extras.segwitTotalWeight,
block.extras.medianFeeAmt, block.extras.medianFeeAmt,
block.extras.coinbaseSignatureAscii, truncatedCoinbaseSignatureAscii,
]; ];
await DB.query(query, params); await DB.query(query, params);

View File

@ -72,7 +72,7 @@ class NetworkSyncService {
const graphNodesPubkeys: string[] = []; const graphNodesPubkeys: string[] = [];
for (const node of nodes) { for (const node of nodes) {
const latestUpdated = await channelsApi.$getLatestChannelUpdateForNode(node.pub_key); const latestUpdated = await channelsApi.$getLatestChannelUpdateForNode(node.pub_key);
node.last_update = Math.max(node.last_update, latestUpdated); node.last_update = Math.max(node.last_update ?? 0, latestUpdated);
await nodesApi.$saveNode(node); await nodesApi.$saveNode(node);
graphNodesPubkeys.push(node.pub_key); graphNodesPubkeys.push(node.pub_key);

View File

@ -1,7 +1,7 @@
import { Component, OnInit, OnDestroy, Input, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core'; import { Component, OnInit, OnDestroy, Input, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import { StateService } from '../../services/state.service'; import { StateService } from '../../services/state.service';
import { Observable, Subscription } from 'rxjs'; import { Observable, Subscription } from 'rxjs';
import { Price } from 'src/app/services/price.service'; import { Price } from '../../services/price.service';
@Component({ @Component({
selector: 'app-amount', selector: 'app-amount',

View File

@ -5,7 +5,7 @@ import BlockScene from './block-scene';
import TxSprite from './tx-sprite'; import TxSprite from './tx-sprite';
import TxView from './tx-view'; import TxView from './tx-view';
import { Position } from './sprite-types'; import { Position } from './sprite-types';
import { Price } from 'src/app/services/price.service'; import { Price } from '../../services/price.service';
@Component({ @Component({
selector: 'app-block-overview-graph', selector: 'app-block-overview-graph',

View File

@ -1,7 +1,7 @@
import { Component, ElementRef, ViewChild, Input, OnChanges, ChangeDetectionStrategy } from '@angular/core'; import { Component, ElementRef, ViewChild, Input, OnChanges, ChangeDetectionStrategy } from '@angular/core';
import { TransactionStripped } from '../../interfaces/websocket.interface'; import { TransactionStripped } from '../../interfaces/websocket.interface';
import { Position } from '../../components/block-overview-graph/sprite-types.js'; import { Position } from '../../components/block-overview-graph/sprite-types.js';
import { Price } from 'src/app/services/price.service'; import { Price } from '../../services/price.service';
@Component({ @Component({
selector: 'app-block-overview-tooltip', selector: 'app-block-overview-tooltip',

View File

@ -13,7 +13,7 @@ import { BlockAudit, BlockExtended, TransactionStripped } from '../../interfaces
import { ApiService } from '../../services/api.service'; import { ApiService } from '../../services/api.service';
import { BlockOverviewGraphComponent } from '../../components/block-overview-graph/block-overview-graph.component'; import { BlockOverviewGraphComponent } from '../../components/block-overview-graph/block-overview-graph.component';
import { detectWebGL } from '../../shared/graphs.utils'; import { detectWebGL } from '../../shared/graphs.utils';
import { PriceService, Price } from 'src/app/services/price.service'; import { PriceService, Price } from '../../services/price.service';
@Component({ @Component({
selector: 'app-block', selector: 'app-block',

View File

@ -22,7 +22,7 @@ import { SeoService } from '../../services/seo.service';
import { BlockExtended, CpfpInfo } from '../../interfaces/node-api.interface'; import { BlockExtended, CpfpInfo } from '../../interfaces/node-api.interface';
import { LiquidUnblinding } from './liquid-ublinding'; import { LiquidUnblinding } from './liquid-ublinding';
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe'; import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
import { Price, PriceService } from 'src/app/services/price.service'; import { Price, PriceService } from '../../services/price.service';
@Component({ @Component({
selector: 'app-transaction', selector: 'app-transaction',

View File

@ -9,7 +9,7 @@ import { AssetsService } from '../../services/assets.service';
import { filter, map, tap, switchMap, shareReplay } from 'rxjs/operators'; import { filter, map, tap, switchMap, shareReplay } from 'rxjs/operators';
import { BlockExtended } from '../../interfaces/node-api.interface'; import { BlockExtended } from '../../interfaces/node-api.interface';
import { ApiService } from '../../services/api.service'; import { ApiService } from '../../services/api.service';
import { PriceService } from 'src/app/services/price.service'; import { PriceService } from '../../services/price.service';
@Component({ @Component({
selector: 'app-transactions-list', selector: 'app-transactions-list',

View File

@ -1,6 +1,6 @@
import { Component, ElementRef, ViewChild, Input, OnChanges, OnInit } from '@angular/core'; import { Component, ElementRef, ViewChild, Input, OnChanges, OnInit } from '@angular/core';
import { tap } from 'rxjs'; import { tap } from 'rxjs';
import { Price, PriceService } from 'src/app/services/price.service'; import { Price, PriceService } from '../../services/price.service';
interface Xput { interface Xput {
type: 'input' | 'output' | 'fee'; type: 'input' | 'output' | 'fee';

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff