Merge branch 'master' into simon/logo-vertical-center-fix
This commit is contained in:
		
						commit
						9bf04b0af4
					
				@ -5,7 +5,7 @@ class NodesApi {
 | 
			
		||||
  public async $getNode(public_key: string): Promise<any> {
 | 
			
		||||
    try {
 | 
			
		||||
      const query = `
 | 
			
		||||
        SELECT nodes.*, geo_names_as.names as as_organization, geo_names_city.names as city,
 | 
			
		||||
        SELECT nodes.*, geo_names_iso.names as iso_code, geo_names_as.names as as_organization, geo_names_city.names as city,
 | 
			
		||||
        geo_names_country.names as country, geo_names_subdivision.names as subdivision,
 | 
			
		||||
          (SELECT Count(*)
 | 
			
		||||
          FROM channels
 | 
			
		||||
@ -24,6 +24,7 @@ class NodesApi {
 | 
			
		||||
        LEFT JOIN geo_names geo_names_city on geo_names_city.id = city_id
 | 
			
		||||
        LEFT JOIN geo_names geo_names_subdivision on geo_names_subdivision.id = subdivision_id
 | 
			
		||||
        LEFT JOIN geo_names geo_names_country on geo_names_country.id = country_id
 | 
			
		||||
        LEFT JOIN geo_names geo_names_iso ON geo_names_iso.id = nodes.country_id AND geo_names_iso.type = 'country_iso_code'
 | 
			
		||||
        WHERE public_key = ?
 | 
			
		||||
      `;
 | 
			
		||||
      const [rows]: any = await DB.query(query, [public_key, public_key, public_key, public_key, public_key, public_key, public_key, public_key, public_key]);
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@ class StatisticsApi {
 | 
			
		||||
      query += ` WHERE added BETWEEN DATE_SUB(NOW(), INTERVAL ${interval}) AND NOW()`;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    query += ` ORDER BY id DESC`;
 | 
			
		||||
    query += ` ORDER BY added DESC`;
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      const [rows]: any = await DB.query(query);
 | 
			
		||||
@ -26,8 +26,8 @@ class StatisticsApi {
 | 
			
		||||
 | 
			
		||||
  public async $getLatestStatistics(): Promise<any> {
 | 
			
		||||
    try {
 | 
			
		||||
      const [rows]: any = await DB.query(`SELECT * FROM lightning_stats ORDER BY id DESC LIMIT 1`);
 | 
			
		||||
      const [rows2]: any = await DB.query(`SELECT * FROM lightning_stats ORDER BY id DESC LIMIT 1 OFFSET 7`);
 | 
			
		||||
      const [rows]: any = await DB.query(`SELECT * FROM lightning_stats ORDER BY added DESC LIMIT 1`);
 | 
			
		||||
      const [rows2]: any = await DB.query(`SELECT * FROM lightning_stats ORDER BY added DESC LIMIT 1 OFFSET 7`);
 | 
			
		||||
      return {
 | 
			
		||||
        latest: rows[0],
 | 
			
		||||
        previous: rows2[0],
 | 
			
		||||
 | 
			
		||||
@ -5,9 +5,9 @@ const P2SH_P2WSH_COST  = 35 * 4; // the WU cost for the non-witness part of P2SH
 | 
			
		||||
 | 
			
		||||
export function calcSegwitFeeGains(tx: Transaction) {
 | 
			
		||||
  // calculated in weight units
 | 
			
		||||
  let realizedBech32Gains = 0;
 | 
			
		||||
  let potentialBech32Gains = 0;
 | 
			
		||||
  let potentialP2shGains = 0;
 | 
			
		||||
  let realizedSegwitGains = 0;
 | 
			
		||||
  let potentialSegwitGains = 0;
 | 
			
		||||
  let potentialP2shSegwitGains = 0;
 | 
			
		||||
  let potentialTaprootGains = 0;
 | 
			
		||||
  let realizedTaprootGains = 0;
 | 
			
		||||
 | 
			
		||||
@ -24,31 +24,33 @@ export function calcSegwitFeeGains(tx: Transaction) {
 | 
			
		||||
    const isP2tr         = vin.prevout.scriptpubkey_type === 'v1_p2tr';
 | 
			
		||||
 | 
			
		||||
    const op = vin.scriptsig ? vin.scriptsig_asm.split(' ')[0] : null;
 | 
			
		||||
    const isP2sh2Wpkh = isP2sh && !!vin.witness && op === 'OP_PUSHBYTES_22';
 | 
			
		||||
    const isP2sh2Wsh  = isP2sh && !!vin.witness && op === 'OP_PUSHBYTES_34';
 | 
			
		||||
    const isP2shP2Wpkh = isP2sh && !!vin.witness && op === 'OP_PUSHBYTES_22';
 | 
			
		||||
    const isP2shP2Wsh  = isP2sh && !!vin.witness && op === 'OP_PUSHBYTES_34';
 | 
			
		||||
 | 
			
		||||
    switch (true) {
 | 
			
		||||
      // Native Segwit - P2WPKH/P2WSH (Bech32)
 | 
			
		||||
      // Native Segwit - P2WPKH/P2WSH/P2TR
 | 
			
		||||
      case isP2wpkh:
 | 
			
		||||
      case isP2wsh:
 | 
			
		||||
      case isP2tr:
 | 
			
		||||
        // maximal gains: the scriptSig is moved entirely to the witness part
 | 
			
		||||
        realizedBech32Gains += witnessSize(vin) * 3;
 | 
			
		||||
        // if taproot is used savings are 42 WU higher because it produces smaller signatures and doesn't require a pubkey in the witness
 | 
			
		||||
        // this number is explained above `realizedTaprootGains += 42;`
 | 
			
		||||
        realizedSegwitGains += (witnessSize(vin) + (isP2tr ? 42 : 0)) * 3;
 | 
			
		||||
        // XXX P2WSH output creation is more expensive, should we take this into consideration?
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      // Backward compatible Segwit - P2SH-P2WPKH
 | 
			
		||||
      case isP2sh2Wpkh:
 | 
			
		||||
        // the scriptSig is moved to the witness, but we have extra 21 extra non-witness bytes (48 WU)
 | 
			
		||||
        realizedBech32Gains += witnessSize(vin) * 3 - P2SH_P2WPKH_COST;
 | 
			
		||||
        potentialBech32Gains += P2SH_P2WPKH_COST;
 | 
			
		||||
      case isP2shP2Wpkh:
 | 
			
		||||
        // the scriptSig is moved to the witness, but we have extra 21 extra non-witness bytes (84 WU)
 | 
			
		||||
        realizedSegwitGains += witnessSize(vin) * 3 - P2SH_P2WPKH_COST;
 | 
			
		||||
        potentialSegwitGains += P2SH_P2WPKH_COST;
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      // Backward compatible Segwit - P2SH-P2WSH
 | 
			
		||||
      case isP2sh2Wsh:
 | 
			
		||||
        // the scriptSig is moved to the witness, but we have extra 35 extra non-witness bytes
 | 
			
		||||
        realizedBech32Gains += witnessSize(vin) * 3 - P2SH_P2WSH_COST;
 | 
			
		||||
        potentialBech32Gains += P2SH_P2WSH_COST;
 | 
			
		||||
      case isP2shP2Wsh:
 | 
			
		||||
        // the scriptSig is moved to the witness, but we have extra 35 extra non-witness bytes (140 WU)
 | 
			
		||||
        realizedSegwitGains += witnessSize(vin) * 3 - P2SH_P2WSH_COST;
 | 
			
		||||
        potentialSegwitGains += P2SH_P2WSH_COST;
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      // Non-segwit P2PKH/P2SH/P2PK/bare multisig
 | 
			
		||||
@ -56,9 +58,13 @@ export function calcSegwitFeeGains(tx: Transaction) {
 | 
			
		||||
      case isP2sh:
 | 
			
		||||
      case isP2pk:
 | 
			
		||||
      case isBareMultisig: {
 | 
			
		||||
        const fullGains = scriptSigSize(vin) * 3;
 | 
			
		||||
        potentialBech32Gains += fullGains;
 | 
			
		||||
        potentialP2shGains += fullGains - (isP2pkh ? P2SH_P2WPKH_COST : P2SH_P2WSH_COST);
 | 
			
		||||
        let fullGains = scriptSigSize(vin) * 3;
 | 
			
		||||
        if (isBareMultisig) {
 | 
			
		||||
          // a _bare_ multisig has the keys in the output script, but P2SH and P2WSH require them to be in the scriptSig/scriptWitness
 | 
			
		||||
          fullGains -= vin.prevout.scriptpubkey.length / 2;
 | 
			
		||||
        }
 | 
			
		||||
        potentialSegwitGains += fullGains;
 | 
			
		||||
        potentialP2shSegwitGains += fullGains - (isP2pkh ? P2SH_P2WPKH_COST : P2SH_P2WSH_COST);
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@ -79,11 +85,11 @@ export function calcSegwitFeeGains(tx: Transaction) {
 | 
			
		||||
        // TODO maybe add some complex scripts that are specified somewhere, so that size is known, such as lightning scripts
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      const script = isP2sh2Wsh || isP2wsh ? vin.inner_witnessscript_asm : vin.inner_redeemscript_asm;
 | 
			
		||||
      const script = isP2shP2Wsh || isP2wsh ? vin.inner_witnessscript_asm : vin.inner_redeemscript_asm;
 | 
			
		||||
      let replacementSize: number;
 | 
			
		||||
      if (
 | 
			
		||||
        // single sig
 | 
			
		||||
        isP2pk || isP2pkh || isP2wpkh || isP2sh2Wpkh ||
 | 
			
		||||
        isP2pk || isP2pkh || isP2wpkh || isP2shP2Wpkh ||
 | 
			
		||||
        // multisig
 | 
			
		||||
        isBareMultisig || parseMultisigScript(script)
 | 
			
		||||
      ) {
 | 
			
		||||
@ -105,11 +111,11 @@ export function calcSegwitFeeGains(tx: Transaction) {
 | 
			
		||||
 | 
			
		||||
  // returned as percentage of the total tx weight
 | 
			
		||||
  return {
 | 
			
		||||
    realizedBech32Gains: realizedBech32Gains / (tx.weight + realizedBech32Gains), // percent of the pre-segwit tx size
 | 
			
		||||
    potentialBech32Gains: potentialBech32Gains / tx.weight,
 | 
			
		||||
    potentialP2shGains: potentialP2shGains / tx.weight,
 | 
			
		||||
    realizedSegwitGains: realizedSegwitGains / (tx.weight + realizedSegwitGains), // percent of the pre-segwit tx size
 | 
			
		||||
    potentialSegwitGains: potentialSegwitGains / tx.weight,
 | 
			
		||||
    potentialP2shSegwitGains: potentialP2shSegwitGains / tx.weight,
 | 
			
		||||
    potentialTaprootGains: potentialTaprootGains / tx.weight,
 | 
			
		||||
    realizedTaprootGains: realizedTaprootGains / tx.weight
 | 
			
		||||
    realizedTaprootGains: realizedTaprootGains / (tx.weight + realizedTaprootGains)
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -188,12 +194,12 @@ export function moveDec(num: number, n: number) {
 | 
			
		||||
  return neg + (int || '0') + (frac.length ? '.' + frac : '');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function zeros(n) {
 | 
			
		||||
function zeros(n: number) {
 | 
			
		||||
  return new Array(n + 1).join('0');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Formats a number for display. Treats the number as a string to avoid rounding errors.
 | 
			
		||||
export const formatNumber = (s, precision = null) => {
 | 
			
		||||
export const formatNumber = (s: number | string, precision: number | null = null) => {
 | 
			
		||||
  let [ whole, dec ] = s.toString().split('.');
 | 
			
		||||
 | 
			
		||||
  // divide numbers into groups of three separated with a thin space (U+202F, "NARROW NO-BREAK SPACE"),
 | 
			
		||||
@ -219,27 +225,27 @@ const witnessSize = (vin: Vin) => vin.witness ? vin.witness.reduce((S, w) => S +
 | 
			
		||||
const scriptSigSize = (vin: Vin) => vin.scriptsig ? vin.scriptsig.length / 2 : 0;
 | 
			
		||||
 | 
			
		||||
// Power of ten wrapper
 | 
			
		||||
export function selectPowerOfTen(val: number) {
 | 
			
		||||
export function selectPowerOfTen(val: number): { divider: number, unit: string } {
 | 
			
		||||
  const powerOfTen = {
 | 
			
		||||
    exa: Math.pow(10, 18),
 | 
			
		||||
    peta: Math.pow(10, 15),
 | 
			
		||||
    terra: Math.pow(10, 12),
 | 
			
		||||
    tera: Math.pow(10, 12),
 | 
			
		||||
    giga: Math.pow(10, 9),
 | 
			
		||||
    mega: Math.pow(10, 6),
 | 
			
		||||
    kilo: Math.pow(10, 3),
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  let selectedPowerOfTen;
 | 
			
		||||
  let selectedPowerOfTen: { divider: number, unit: string };
 | 
			
		||||
  if (val < powerOfTen.kilo) {
 | 
			
		||||
    selectedPowerOfTen = { divider: 1, unit: '' }; // no scaling
 | 
			
		||||
  } else if (val < powerOfTen.mega) {
 | 
			
		||||
    selectedPowerOfTen = { divider: powerOfTen.kilo, unit: 'k' };
 | 
			
		||||
  } else if (val < powerOfTen.giga) {
 | 
			
		||||
    selectedPowerOfTen = { divider: powerOfTen.mega, unit: 'M' };
 | 
			
		||||
  } else if (val < powerOfTen.terra) {
 | 
			
		||||
  } else if (val < powerOfTen.tera) {
 | 
			
		||||
    selectedPowerOfTen = { divider: powerOfTen.giga, unit: 'G' };
 | 
			
		||||
  } else if (val < powerOfTen.peta) {
 | 
			
		||||
    selectedPowerOfTen = { divider: powerOfTen.terra, unit: 'T' };
 | 
			
		||||
    selectedPowerOfTen = { divider: powerOfTen.tera, unit: 'T' };
 | 
			
		||||
  } else if (val < powerOfTen.exa) {
 | 
			
		||||
    selectedPowerOfTen = { divider: powerOfTen.peta, unit: 'P' };
 | 
			
		||||
  } else {
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,12 @@
 | 
			
		||||
<span *ngIf="segwitGains.realizedBech32Gains && !segwitGains.potentialBech32Gains; else segwitTwo" class="badge badge-success mr-1" i18n-ngbTooltip="ngbTooltip about segwit gains" ngbTooltip="This transaction saved {{ segwitGains.realizedBech32Gains * 100 | number:  '1.0-0' }}% on fees by using native SegWit-Bech32" placement="bottom" i18n="tx-features.tag.segwit|SegWit">SegWit</span>
 | 
			
		||||
<span *ngIf="segwitGains.realizedSegwitGains && !segwitGains.potentialSegwitGains; else segwitTwo" class="badge badge-success mr-1" i18n-ngbTooltip="ngbTooltip about segwit gains" ngbTooltip="This transaction saved {{ segwitGains.realizedSegwitGains * 100 | number:  '1.0-0' }}% on fees by using native SegWit" placement="bottom" i18n="tx-features.tag.segwit|SegWit">SegWit</span>
 | 
			
		||||
<ng-template #segwitTwo>
 | 
			
		||||
  <span *ngIf="segwitGains.realizedBech32Gains && segwitGains.potentialBech32Gains; else potentialP2shGains" class="badge badge-warning mr-1" i18n-ngbTooltip="ngbTooltip about double segwit gains" ngbTooltip="This transaction saved {{ segwitGains.realizedBech32Gains * 100 | number:  '1.0-0' }}% on fees by using SegWit and could save {{ segwitGains.potentialBech32Gains * 100 | number : '1.0-0' }}% more by fully upgrading to native SegWit-Bech32" placement="bottom" i18n="tx-features.tag.segwit|SegWit">SegWit</span>
 | 
			
		||||
  <ng-template #potentialP2shGains>
 | 
			
		||||
    <span *ngIf="segwitGains.potentialP2shGains" class="badge badge-danger mr-1" i18n-ngbTooltip="ngbTooltip about missed out gains" ngbTooltip="This transaction could save {{ segwitGains.potentialBech32Gains * 100 | number : '1.0-0' }}% on fees by upgrading to native SegWit-Bech32 or {{ segwitGains.potentialP2shGains * 100 | number:  '1.0-0' }}% by upgrading to SegWit-P2SH" placement="bottom"><del i18n="tx-features.tag.segwit|SegWit">SegWit</del></span>
 | 
			
		||||
  <span *ngIf="segwitGains.realizedSegwitGains && segwitGains.potentialSegwitGains; else potentialP2shSegwitGains" class="badge badge-warning mr-1" i18n-ngbTooltip="ngbTooltip about double segwit gains" ngbTooltip="This transaction saved {{ segwitGains.realizedSegwitGains * 100 | number:  '1.0-0' }}% on fees by using SegWit and could save {{ segwitGains.potentialSegwitGains * 100 | number : '1.0-0' }}% more by fully upgrading to native SegWit" placement="bottom" i18n="tx-features.tag.segwit|SegWit">SegWit</span>
 | 
			
		||||
  <ng-template #potentialP2shSegwitGains>
 | 
			
		||||
    <span *ngIf="segwitGains.potentialP2shSegwitGains" class="badge badge-danger mr-1" i18n-ngbTooltip="ngbTooltip about missed out gains" ngbTooltip="This transaction could save {{ segwitGains.potentialSegwitGains * 100 | number : '1.0-0' }}% on fees by upgrading to native SegWit or {{ segwitGains.potentialP2shSegwitGains * 100 | number:  '1.0-0' }}% by upgrading to SegWit-P2SH" placement="bottom"><del i18n="tx-features.tag.segwit|SegWit">SegWit</del></span>
 | 
			
		||||
  </ng-template>
 | 
			
		||||
</ng-template>
 | 
			
		||||
 | 
			
		||||
<span *ngIf="segwitGains.realizedTaprootGains && !segwitGains.potentialTaprootGains; else notFullyTaproot" class="badge badge-success mr-1" i18n-ngbTooltip="Tooltip about privacy and fees saved with taproot" ngbTooltip="This transaction uses Taproot and the user's thereby increased privacy and saved at least {{ segwitGains.realizedTaprootGains * 100 | number: '1.0-0' }}% on fees" placement="bottom" i18n="tx-features.tag.taproot|Taproot">Taproot</span>
 | 
			
		||||
<span *ngIf="segwitGains.realizedTaprootGains && !segwitGains.potentialTaprootGains; else notFullyTaproot" class="badge badge-success mr-1" i18n-ngbTooltip="Tooltip about privacy and fees saved with taproot" ngbTooltip="This transaction uses Taproot and thereby increased the user's privacy and saved at least {{ segwitGains.realizedTaprootGains * 100 | number: '1.0-0' }}% on fees" placement="bottom" i18n="tx-features.tag.taproot|Taproot">Taproot</span>
 | 
			
		||||
<ng-template #notFullyTaproot>
 | 
			
		||||
  <span *ngIf="segwitGains.realizedTaprootGains && segwitGains.potentialTaprootGains; else noTaproot" class="badge badge-warning mr-1" i18n-ngbTooltip="Tooltip about privacy and more fees that could be saved with more taproot" ngbTooltip="This transaction uses Taproot and thereby increased the user's privacy and already saved at least {{ segwitGains.realizedTaprootGains * 100 | number: '1.0-0' }}% on fees, but could save an additional {{ segwitGains.potentialTaprootGains * 100 | number: '1.0-0' }}% by fully using Taproot" placement="bottom" i18n="tx-features.tag.taproot|Taproot">Taproot</span>
 | 
			
		||||
  <ng-template #noTaproot>
 | 
			
		||||
 | 
			
		||||
@ -12,9 +12,9 @@ export class TxFeaturesComponent implements OnChanges {
 | 
			
		||||
  @Input() tx: Transaction;
 | 
			
		||||
 | 
			
		||||
  segwitGains = {
 | 
			
		||||
    realizedBech32Gains: 0,
 | 
			
		||||
    potentialBech32Gains: 0,
 | 
			
		||||
    potentialP2shGains: 0,
 | 
			
		||||
    realizedSegwitGains: 0,
 | 
			
		||||
    potentialSegwitGains: 0,
 | 
			
		||||
    potentialP2shSegwitGains: 0,
 | 
			
		||||
    potentialTaprootGains: 0,
 | 
			
		||||
    realizedTaprootGains: 0
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
@ -169,9 +169,6 @@ export class NodeStatisticsChartComponent implements OnInit {
 | 
			
		||||
      },
 | 
			
		||||
      yAxis: data.channels.length === 0 ? undefined : [
 | 
			
		||||
        {
 | 
			
		||||
          min: (value) => {
 | 
			
		||||
            return value.min * 0.9;
 | 
			
		||||
          },
 | 
			
		||||
          type: 'value',
 | 
			
		||||
          axisLabel: {
 | 
			
		||||
            color: 'rgb(110, 112, 121)',
 | 
			
		||||
@ -188,9 +185,6 @@ export class NodeStatisticsChartComponent implements OnInit {
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          min: (value) => {
 | 
			
		||||
            return value.min * 0.9;
 | 
			
		||||
          },
 | 
			
		||||
          type: 'value',
 | 
			
		||||
          position: 'right',
 | 
			
		||||
          axisLabel: {
 | 
			
		||||
@ -225,15 +219,6 @@ export class NodeStatisticsChartComponent implements OnInit {
 | 
			
		||||
              opacity: 1,
 | 
			
		||||
              width: 1,
 | 
			
		||||
            },
 | 
			
		||||
            data: [{
 | 
			
		||||
              yAxis: 1,
 | 
			
		||||
              label: {
 | 
			
		||||
                position: 'end',
 | 
			
		||||
                show: true,
 | 
			
		||||
                color: '#ffffff',
 | 
			
		||||
                formatter: `1 MB`
 | 
			
		||||
              }
 | 
			
		||||
            }],
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
@ -43,11 +43,23 @@
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr *ngIf="node.country && node.city && node.subdivision">
 | 
			
		||||
              <td i18n="location">Location</td>
 | 
			
		||||
              <td>{{ node.city.en }}, {{ node.subdivision.en }}<br>{{ node.country.en }}</td>
 | 
			
		||||
              <td>
 | 
			
		||||
                <span>{{ node.city.en }}, {{ node.subdivision.en }}</span>
 | 
			
		||||
                <br>
 | 
			
		||||
                <a class="d-flex align-items-center" [routerLink]="['/lightning/nodes/country' | relativeUrl, node.iso_code]">
 | 
			
		||||
                  <span class="link">{{ node.country.en }}</span>
 | 
			
		||||
                   
 | 
			
		||||
                  <span class="flag">{{ node.flag }}</span>
 | 
			
		||||
                </a>
 | 
			
		||||
              </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr *ngIf="node.country && !node.city">
 | 
			
		||||
              <td i18n="location">Location</td>
 | 
			
		||||
              <td>{{ node.country.en }}</td>
 | 
			
		||||
              <td>
 | 
			
		||||
                <a [routerLink]="['/lightning/nodes/country' | relativeUrl, node.iso_code]">
 | 
			
		||||
                  {{ node.country.en }} {{ node.flag }}
 | 
			
		||||
                </a>
 | 
			
		||||
              </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
          </tbody>
 | 
			
		||||
        </table>
 | 
			
		||||
@ -77,7 +89,9 @@
 | 
			
		||||
            <tr *ngIf="node.country">
 | 
			
		||||
              <td i18n="isp">ISP</td>
 | 
			
		||||
              <td>
 | 
			
		||||
                {{ node.as_organization }} [ASN {{node.as_number}}]
 | 
			
		||||
                <a [routerLink]="['/lightning/nodes/isp' | relativeUrl, node.as_number]">
 | 
			
		||||
                  {{ node.as_organization }} [ASN {{node.as_number}}]
 | 
			
		||||
                </a>                
 | 
			
		||||
              </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
          </tbody>
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,7 @@ import { ActivatedRoute, ParamMap } from '@angular/router';
 | 
			
		||||
import { Observable } from 'rxjs';
 | 
			
		||||
import { catchError, map, switchMap } from 'rxjs/operators';
 | 
			
		||||
import { SeoService } from 'src/app/services/seo.service';
 | 
			
		||||
import { getFlagEmoji } from 'src/app/shared/graphs.utils';
 | 
			
		||||
import { LightningApiService } from '../lightning-api.service';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
@ -51,6 +52,7 @@ export class NodeComponent implements OnInit {
 | 
			
		||||
            } else if (socket.indexOf('onion') > -1) {
 | 
			
		||||
              label = 'Tor';
 | 
			
		||||
            }
 | 
			
		||||
            node.flag = getFlagEmoji(node.iso_code);
 | 
			
		||||
            socketsObject.push({
 | 
			
		||||
              label: label,
 | 
			
		||||
              socket: node.public_key + '@' + socket,
 | 
			
		||||
 | 
			
		||||
@ -59,7 +59,7 @@ export class NodesNetworksChartComponent implements OnInit {
 | 
			
		||||
    let firstRun = true;
 | 
			
		||||
 | 
			
		||||
    if (this.widget) {
 | 
			
		||||
      this.miningWindowPreference = '1y';
 | 
			
		||||
      this.miningWindowPreference = '3y';
 | 
			
		||||
    } else {
 | 
			
		||||
      this.seoService.setTitle($localize`Lightning nodes per network`);
 | 
			
		||||
      this.miningWindowPreference = this.miningService.getDefaultTimespan('all');
 | 
			
		||||
 | 
			
		||||
@ -58,7 +58,7 @@ export class LightningStatisticsChartComponent implements OnInit {
 | 
			
		||||
    let firstRun = true;
 | 
			
		||||
 | 
			
		||||
    if (this.widget) {
 | 
			
		||||
      this.miningWindowPreference = '1y';
 | 
			
		||||
      this.miningWindowPreference = '3y';
 | 
			
		||||
    } else {
 | 
			
		||||
      this.seoService.setTitle($localize`Channels and Capacity`);
 | 
			
		||||
      this.miningWindowPreference = this.miningService.getDefaultTimespan('all');
 | 
			
		||||
 | 
			
		||||
@ -92,6 +92,9 @@ export function detectWebGL() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getFlagEmoji(countryCode) {
 | 
			
		||||
  if (!countryCode) {
 | 
			
		||||
    return '';
 | 
			
		||||
  }
 | 
			
		||||
  const codePoints = countryCode
 | 
			
		||||
    .toUpperCase()
 | 
			
		||||
    .split('')
 | 
			
		||||
 | 
			
		||||
@ -18,12 +18,18 @@ whitelist=2401:b140::/32
 | 
			
		||||
#uacomment=@wiz
 | 
			
		||||
 | 
			
		||||
[main]
 | 
			
		||||
bind=0.0.0.0:8333
 | 
			
		||||
bind=[::]:8333
 | 
			
		||||
rpcbind=127.0.0.1:8332
 | 
			
		||||
rpcbind=[::1]:8332
 | 
			
		||||
zmqpubrawblock=tcp://127.0.0.1:18332
 | 
			
		||||
zmqpubrawtx=tcp://127.0.0.1:18333
 | 
			
		||||
bind=0.0.0.0:8333
 | 
			
		||||
bind=[::]:8333
 | 
			
		||||
zmqpubrawblock=tcp://127.0.0.1:8334
 | 
			
		||||
zmqpubrawtx=tcp://127.0.0.1:8335
 | 
			
		||||
#addnode=[2401:b140:1::92:201]:8333
 | 
			
		||||
#addnode=[2401:b140:1::92:202]:8333
 | 
			
		||||
#addnode=[2401:b140:1::92:203]:8333
 | 
			
		||||
#addnode=[2401:b140:1::92:204]:8333
 | 
			
		||||
#addnode=[2401:b140:1::92:205]:8333
 | 
			
		||||
#addnode=[2401:b140:1::92:206]:8333
 | 
			
		||||
#addnode=[2401:b140:2::92:201]:8333
 | 
			
		||||
#addnode=[2401:b140:2::92:202]:8333
 | 
			
		||||
#addnode=[2401:b140:2::92:203]:8333
 | 
			
		||||
@ -33,10 +39,18 @@ zmqpubrawtx=tcp://127.0.0.1:18333
 | 
			
		||||
 | 
			
		||||
[test]
 | 
			
		||||
daemon=1
 | 
			
		||||
bind=0.0.0.0:18333
 | 
			
		||||
bind=[::]:18333
 | 
			
		||||
rpcbind=127.0.0.1:18332
 | 
			
		||||
rpcbind=[::1]:18332
 | 
			
		||||
bind=0.0.0.0:18333
 | 
			
		||||
bind=[::]:18333
 | 
			
		||||
zmqpubrawblock=tcp://127.0.0.1:18334
 | 
			
		||||
zmqpubrawtx=tcp://127.0.0.1:18335
 | 
			
		||||
#addnode=[2401:b140:1::92:201]:18333
 | 
			
		||||
#addnode=[2401:b140:1::92:202]:18333
 | 
			
		||||
#addnode=[2401:b140:1::92:203]:18333
 | 
			
		||||
#addnode=[2401:b140:1::92:204]:18333
 | 
			
		||||
#addnode=[2401:b140:1::92:205]:18333
 | 
			
		||||
#addnode=[2401:b140:1::92:206]:18333
 | 
			
		||||
#addnode=[2401:b140:2::92:201]:18333
 | 
			
		||||
#addnode=[2401:b140:2::92:202]:18333
 | 
			
		||||
#addnode=[2401:b140:2::92:203]:18333
 | 
			
		||||
@ -46,10 +60,18 @@ rpcbind=[::1]:18332
 | 
			
		||||
 | 
			
		||||
[signet]
 | 
			
		||||
daemon=1
 | 
			
		||||
bind=0.0.0.0:38333
 | 
			
		||||
bind=[::]:38333
 | 
			
		||||
rpcbind=127.0.0.1:38332
 | 
			
		||||
rpcbind=[::1]:38332
 | 
			
		||||
bind=0.0.0.0:38333
 | 
			
		||||
bind=[::]:38333
 | 
			
		||||
zmqpubrawblock=tcp://127.0.0.1:38334
 | 
			
		||||
zmqpubrawtx=tcp://127.0.0.1:38335
 | 
			
		||||
#addnode=[2401:b140:1::92:201]:38333
 | 
			
		||||
#addnode=[2401:b140:1::92:202]:38333
 | 
			
		||||
#addnode=[2401:b140:1::92:203]:38333
 | 
			
		||||
#addnode=[2401:b140:1::92:204]:38333
 | 
			
		||||
#addnode=[2401:b140:1::92:205]:38333
 | 
			
		||||
#addnode=[2401:b140:1::92:206]:38333
 | 
			
		||||
#addnode=[2401:b140:2::92:201]:38333
 | 
			
		||||
#addnode=[2401:b140:2::92:202]:38333
 | 
			
		||||
#addnode=[2401:b140:2::92:203]:38333
 | 
			
		||||
 | 
			
		||||
@ -218,6 +218,21 @@ MYSQL_HOME=/mysql
 | 
			
		||||
MYSQL_USER=mysql
 | 
			
		||||
MYSQL_GROUP=mysql
 | 
			
		||||
 | 
			
		||||
# mempool mysql user/password
 | 
			
		||||
MEMPOOL_MAINNET_USER='mempool'
 | 
			
		||||
MEMPOOL_TESTNET_USER='mempool_testnet'
 | 
			
		||||
MEMPOOL_SIGNET_USER='mempool_signet'
 | 
			
		||||
MEMPOOL_LIQUID_USER='mempool_liquid'
 | 
			
		||||
MEMPOOL_LIQUIDTESTNET_USER='mempool_liquidtestnet'
 | 
			
		||||
MEMPOOL_BISQ_USER='mempool_bisq'
 | 
			
		||||
# generate random hex string
 | 
			
		||||
MEMPOOL_MAINNET_PASS=$(head -150 /dev/urandom | ${MD5} | awk '{print $1}')
 | 
			
		||||
MEMPOOL_TESTNET_PASS=$(head -150 /dev/urandom | ${MD5} | awk '{print $1}')
 | 
			
		||||
MEMPOOL_SIGNET_PASS=$(head -150 /dev/urandom | ${MD5} | awk '{print $1}')
 | 
			
		||||
MEMPOOL_LIQUID_PASS=$(head -150 /dev/urandom | ${MD5} | awk '{print $1}')
 | 
			
		||||
MEMPOOL_LIQUIDTESTNET_PASS=$(head -150 /dev/urandom | ${MD5} | awk '{print $1}')
 | 
			
		||||
MEMPOOL_BISQ_PASS=$(head -150 /dev/urandom | ${MD5} | awk '{print $1}')
 | 
			
		||||
 | 
			
		||||
# mempool data folder and user/group
 | 
			
		||||
MEMPOOL_HOME=/mempool
 | 
			
		||||
MEMPOOL_USER=mempool
 | 
			
		||||
@ -1513,22 +1528,38 @@ esac
 | 
			
		||||
 | 
			
		||||
mysql << _EOF_
 | 
			
		||||
create database mempool;
 | 
			
		||||
grant all on mempool.* to 'mempool'@'localhost' identified by 'mempool';
 | 
			
		||||
grant all on mempool.* to '${MEMPOOL_MAINNET_USER}'@'localhost' identified by '${MEMPOOL_MAINNET_PASS}';
 | 
			
		||||
 | 
			
		||||
create database mempool_testnet;
 | 
			
		||||
grant all on mempool_testnet.* to 'mempool_testnet'@'localhost' identified by 'mempool_testnet';
 | 
			
		||||
grant all on mempool_testnet.* to '${MEMPOOL_TESTNET_USER}'@'localhost' identified by '${MEMPOOL_TESTNET_PASS}';
 | 
			
		||||
 | 
			
		||||
create database mempool_signet;
 | 
			
		||||
grant all on mempool_signet.* to 'mempool_signet'@'localhost' identified by 'mempool_signet';
 | 
			
		||||
grant all on mempool_signet.* to '${MEMPOOL_SIGNET_USER}'@'localhost' identified by '${MEMPOOL_SIGNET_PASS}';
 | 
			
		||||
 | 
			
		||||
create database mempool_liquid;
 | 
			
		||||
grant all on mempool_liquid.* to 'mempool_liquid'@'localhost' identified by 'mempool_liquid';
 | 
			
		||||
grant all on mempool_liquid.* to '${MEMPOOL_LIQUID_USER}'@'localhost' identified by '${MEMPOOL_LIQUID_PASS}';
 | 
			
		||||
 | 
			
		||||
create database mempool_liquidtestnet;
 | 
			
		||||
grant all on mempool_liquidtestnet.* to 'mempool_liquidtestnet'@'localhost' identified by 'mempool_liquidtestnet';
 | 
			
		||||
grant all on mempool_liquidtestnet.* to '${MEMPOOL_LIQUIDTESTNET_USER}'@'localhost' identified by '${MEMPOOL_LIQUIDTESTNET_PASS}';
 | 
			
		||||
 | 
			
		||||
create database mempool_bisq;
 | 
			
		||||
grant all on mempool_bisq.* to 'mempool_bisq'@'localhost' identified by 'mempool_bisq';
 | 
			
		||||
grant all on mempool_bisq.* to '${MEMPOOL_BISQ_USER}'@'localhost' identified by '${MEMPOOL_BISQ_PASS}';
 | 
			
		||||
_EOF_
 | 
			
		||||
 | 
			
		||||
echo "[*] save MySQL credentials"
 | 
			
		||||
cat > ${MEMPOOL_HOME}/mysql_credentials << _EOF_
 | 
			
		||||
declare -x MEMPOOL_MAINNET_USER="${MEMPOOL_MAINNET_USER}"
 | 
			
		||||
declare -x MEMPOOL_MAINNET_PASS="${MEMPOOL_MAINNET_PASS}"
 | 
			
		||||
declare -x MEMPOOL_TESTNET_USER="${MEMPOOL_TESTNET_USER}"
 | 
			
		||||
declare -x MEMPOOL_TESTNET_PASS="${MEMPOOL_TESTNET_PASS}"
 | 
			
		||||
declare -x MEMPOOL_SIGNET_USER="${MEMPOOL_SIGNET_USER}"
 | 
			
		||||
declare -x MEMPOOL_SIGNET_PASS="${MEMPOOL_SIGNET_PASS}"
 | 
			
		||||
declare -x MEMPOOL_LIQUID_USER="${MEMPOOL_LIQUID_USER}"
 | 
			
		||||
declare -x MEMPOOL_LIQUID_PASS="${MEMPOOL_LIQUID_PASS}"
 | 
			
		||||
declare -x MEMPOOL_LIQUIDTESTNET_USER="${MEMPOOL_LIQUIDTESTNET_USER}"
 | 
			
		||||
declare -x MEMPOOL_LIQUIDTESTNET_PASS="${MEMPOOL_LIQUIDTESTNET_PASS}"
 | 
			
		||||
declare -x MEMPOOL_BISQ_USER="${MEMPOOL_BISQ_USER}"
 | 
			
		||||
declare -x MEMPOOL_BISQ_PASS="${MEMPOOL_BISQ_PASS}"
 | 
			
		||||
_EOF_
 | 
			
		||||
 | 
			
		||||
##### nginx
 | 
			
		||||
 | 
			
		||||
@ -11,6 +11,9 @@ BITCOIN_RPC_PASS=$(grep '^rpcpassword' /bitcoin/bitcoin.conf | cut -d '=' -f2)
 | 
			
		||||
ELEMENTS_RPC_USER=$(grep '^rpcuser' /elements/elements.conf | cut -d '=' -f2)
 | 
			
		||||
ELEMENTS_RPC_PASS=$(grep '^rpcpassword' /elements/elements.conf | cut -d '=' -f2)
 | 
			
		||||
 | 
			
		||||
# get mysql credentials
 | 
			
		||||
. /mempool/mysql_credentials
 | 
			
		||||
 | 
			
		||||
if [ -f "${LOCKFILE}" ];then
 | 
			
		||||
    echo "upgrade already running? check lockfile ${LOCKFILE}"
 | 
			
		||||
    exit 1
 | 
			
		||||
@ -73,6 +76,18 @@ build_backend()
 | 
			
		||||
	-e "s!__BITCOIN_RPC_PASS__!${BITCOIN_RPC_PASS}!" \
 | 
			
		||||
	-e "s!__ELEMENTS_RPC_USER__!${ELEMENTS_RPC_USER}!" \
 | 
			
		||||
	-e "s!__ELEMENTS_RPC_PASS__!${ELEMENTS_RPC_PASS}!" \
 | 
			
		||||
        -e "s!__MEMPOOL_MAINNET_USER__!${MEMPOOL_MAINNET_USER}!" \
 | 
			
		||||
        -e "s!__MEMPOOL_MAINNET_PASS__!${MEMPOOL_MAINNET_PASS}!" \
 | 
			
		||||
        -e "s!__MEMPOOL_TESTNET_USER__!${MEMPOOL_TESTNET_USER}!" \
 | 
			
		||||
        -e "s!__MEMPOOL_TESTNET_PASS__!${MEMPOOL_TESTNET_PASS}!" \
 | 
			
		||||
        -e "s!__MEMPOOL_SIGNET_USER__!${MEMPOOL_SIGNET_USER}!" \
 | 
			
		||||
        -e "s!__MEMPOOL_SIGNET_PASS__!${MEMPOOL_SIGNET_PASS}!" \
 | 
			
		||||
        -e "s!__MEMPOOL_LIQUID_USER__!${MEMPOOL_LIQUID_USER}!" \
 | 
			
		||||
        -e "s!__MEMPOOL_LIQUID_PASS__!${MEMPOOL_LIQUID_PASS}!" \
 | 
			
		||||
        -e "s!__MEMPOOL_LIQUIDTESTNET_USER__!${LIQUIDTESTNET_USER}!" \
 | 
			
		||||
        -e "s!__MEMPOOL_LIQUIDTESTNET_PASS__!${MEMPOOL_LIQUIDTESTNET_PASS}!" \
 | 
			
		||||
        -e "s!__MEMPOOL_BISQ_USER__!${MEMPOOL_BISQ_USER}!" \
 | 
			
		||||
        -e "s!__MEMPOOL_BISQ_PASS__!${MEMPOOL_BISQ_PASS}!" \
 | 
			
		||||
	"mempool-config.json"
 | 
			
		||||
    fi
 | 
			
		||||
    npm install --omit=dev --omit=optional || exit 1
 | 
			
		||||
 | 
			
		||||
@ -21,8 +21,8 @@
 | 
			
		||||
    "ENABLED": false,
 | 
			
		||||
    "HOST": "127.0.0.1",
 | 
			
		||||
    "PORT": 3306,
 | 
			
		||||
    "USERNAME": "mempool_bisq",
 | 
			
		||||
    "PASSWORD": "mempool_bisq",
 | 
			
		||||
    "USERNAME": "__MEMPOOL_BISQ_USER__",
 | 
			
		||||
    "PASSWORD": "__MEMPOOL_BISQ_PASS__",
 | 
			
		||||
    "DATABASE": "mempool_bisq"
 | 
			
		||||
  },
 | 
			
		||||
  "STATISTICS": {
 | 
			
		||||
 | 
			
		||||
@ -28,8 +28,8 @@
 | 
			
		||||
    "ENABLED": true,
 | 
			
		||||
    "HOST": "127.0.0.1",
 | 
			
		||||
    "PORT": 3306,
 | 
			
		||||
    "USERNAME": "mempool_liquid",
 | 
			
		||||
    "PASSWORD": "mempool_liquid",
 | 
			
		||||
    "USERNAME": "__MEMPOOL_LIQUID_USER__",
 | 
			
		||||
    "PASSWORD": "__MEMPOOL_LIQUID_PASS__",
 | 
			
		||||
    "DATABASE": "mempool_liquid"
 | 
			
		||||
  },
 | 
			
		||||
  "STATISTICS": {
 | 
			
		||||
 | 
			
		||||
@ -28,8 +28,8 @@
 | 
			
		||||
    "ENABLED": true,
 | 
			
		||||
    "HOST": "127.0.0.1",
 | 
			
		||||
    "PORT": 3306,
 | 
			
		||||
    "USERNAME": "mempool_liquidtestnet",
 | 
			
		||||
    "PASSWORD": "mempool_liquidtestnet",
 | 
			
		||||
    "USERNAME": "__MEMPOOL_LIQUIDTESTNET_USER__",
 | 
			
		||||
    "PASSWORD": "__MEMPOOL_LIQUIDTESTNET_PASS__",
 | 
			
		||||
    "DATABASE": "mempool_liquidtestnet"
 | 
			
		||||
  },
 | 
			
		||||
  "STATISTICS": {
 | 
			
		||||
 | 
			
		||||
@ -32,8 +32,8 @@
 | 
			
		||||
    "ENABLED": true,
 | 
			
		||||
    "HOST": "127.0.0.1",
 | 
			
		||||
    "PORT": 3306,
 | 
			
		||||
    "USERNAME": "mempool",
 | 
			
		||||
    "PASSWORD": "mempool",
 | 
			
		||||
    "USERNAME": "__MEMPOOL_MAINNET_USER__",
 | 
			
		||||
    "PASSWORD": "__MEMPOOL_MAINNET_PASS__",
 | 
			
		||||
    "DATABASE": "mempool"
 | 
			
		||||
  },
 | 
			
		||||
  "STATISTICS": {
 | 
			
		||||
 | 
			
		||||
@ -24,8 +24,8 @@
 | 
			
		||||
    "ENABLED": true,
 | 
			
		||||
    "HOST": "127.0.0.1",
 | 
			
		||||
    "PORT": 3306,
 | 
			
		||||
    "USERNAME": "mempool_signet",
 | 
			
		||||
    "PASSWORD": "mempool_signet",
 | 
			
		||||
    "USERNAME": "__MEMPOOL_SIGNET_USER__",
 | 
			
		||||
    "PASSWORD": "__MEMPOOL_SIGNET_PASS__",
 | 
			
		||||
    "DATABASE": "mempool_signet"
 | 
			
		||||
  },
 | 
			
		||||
  "STATISTICS": {
 | 
			
		||||
 | 
			
		||||
@ -24,8 +24,8 @@
 | 
			
		||||
    "ENABLED": true,
 | 
			
		||||
    "HOST": "127.0.0.1",
 | 
			
		||||
    "PORT": 3306,
 | 
			
		||||
    "USERNAME": "mempool_testnet",
 | 
			
		||||
    "PASSWORD": "mempool_testnet",
 | 
			
		||||
    "USERNAME": "__MEMPOOL_TESTNET_USER__",
 | 
			
		||||
    "PASSWORD": "__MEMPOOL_TESTNET_PASS__",
 | 
			
		||||
    "DATABASE": "mempool_testnet"
 | 
			
		||||
  },
 | 
			
		||||
  "STATISTICS": {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user