diff --git a/app/lib/dal/drivers/SQLiteDriver.ts b/app/lib/dal/drivers/SQLiteDriver.ts index d034f0a034b07261dde7cff4e10edb65896b2213..404371634614543f04bee34812528d961a5ee043 100644 --- a/app/lib/dal/drivers/SQLiteDriver.ts +++ b/app/lib/dal/drivers/SQLiteDriver.ts @@ -95,16 +95,16 @@ export class SQLiteDriver { } async destroyDatabase(): Promise<void> { - this.logger.debug("Removing SQLite database \"%s\"...", this.path); + this.logger.debug('Removing SQLite database "%s"...', this.path); await this.closeConnection(); if (this.path !== MEMORY_PATH) { await RealFS().fsUnlink(this.path); } - this.logger.debug("Database \"%s\" removed", this.path); + this.logger.debug('Database "%s" removed', this.path); } get closed() { - return this.dbPromise + return this.dbPromise; } async closeConnection(): Promise<void> { @@ -116,9 +116,9 @@ export class SQLiteDriver { db.open; // For an unknown reason, we need this line. } await new Promise((resolve, reject) => { - this.logger.debug("Closing SQLite database \"%s\"...", this.path); + this.logger.debug('Closing SQLite database "%s"...', this.path); db.on("close", () => { - this.logger.info("Database \"%s\" closed.", this.path); + this.logger.info('Database "%s" closed.', this.path); this.dbPromise = null; resolve(); }); diff --git a/app/lib/dal/fileDAL.ts b/app/lib/dal/fileDAL.ts index 100d1cb51ba2e82c0337e9ce9c9c6b9e8123d4d7..2d7915db8d508ca3ab8014d3ef4129a454ff1cb8 100644 --- a/app/lib/dal/fileDAL.ts +++ b/app/lib/dal/fileDAL.ts @@ -13,12 +13,12 @@ import * as fs from "fs"; import * as path from "path"; -import {SQLiteDriver} from "./drivers/SQLiteDriver"; -import {ConfDAL} from "./fileDALs/ConfDAL"; -import {ConfDTO} from "../dto/ConfDTO"; -import {BlockDTO} from "../dto/BlockDTO"; -import {DBHead} from "../db/DBHead"; -import {DBIdentity, IdentityDAL} from "./sqliteDAL/IdentityDAL"; +import { SQLiteDriver } from "./drivers/SQLiteDriver"; +import { ConfDAL } from "./fileDALs/ConfDAL"; +import { ConfDTO } from "../dto/ConfDTO"; +import { BlockDTO } from "../dto/BlockDTO"; +import { DBHead } from "../db/DBHead"; +import { DBIdentity, IdentityDAL } from "./sqliteDAL/IdentityDAL"; import { CindexEntry, FullCindexEntry, @@ -31,55 +31,55 @@ import { SimpleUdEntryForWallet, SindexEntry, } from "../indexer"; -import {TransactionDTO} from "../dto/TransactionDTO"; -import {CertDAL, DBCert} from "./sqliteDAL/CertDAL"; -import {DBBlock} from "../db/DBBlock"; -import {DBMembership, MembershipDAL} from "./sqliteDAL/MembershipDAL"; -import {MerkleDTO} from "../dto/MerkleDTO"; -import {CommonConstants} from "../common-libs/constants"; -import {PowDAL} from "./fileDALs/PowDAL"; -import {Initiable} from "./sqliteDAL/Initiable"; -import {MetaDAL} from "./sqliteDAL/MetaDAL"; -import {DataErrors} from "../common-libs/errors"; -import {BasicRevocableIdentity, IdentityDTO} from "../dto/IdentityDTO"; -import {FileSystem} from "../system/directory"; -import {Wot} from "../../../neon/lib"; -import {IIndexDAO} from "./indexDAL/abstract/IIndexDAO"; -import {BIndexDAO} from "./indexDAL/abstract/BIndexDAO"; -import {MIndexDAO} from "./indexDAL/abstract/MIndexDAO"; -import {SIndexDAO} from "./indexDAL/abstract/SIndexDAO"; -import {CIndexDAO} from "./indexDAL/abstract/CIndexDAO"; -import {IdentityForRequirements} from "../../service/BlockchainService"; -import {BlockchainDAO} from "./indexDAL/abstract/BlockchainDAO"; -import {TxsDAO} from "./indexDAL/abstract/TxsDAO"; -import {WalletDAO} from "./indexDAL/abstract/WalletDAO"; -import {PeerDAO} from "./indexDAL/abstract/PeerDAO"; -import {DBTx} from "../db/DBTx"; -import {DBWallet} from "../db/DBWallet"; -import {Tristamp} from "../common/Tristamp"; -import {CFSCore} from "./fileDALs/CFSCore"; -import {Underscore} from "../common-libs/underscore"; -import {DBPeer} from "../db/DBPeer"; -import {MonitorFlushedIndex} from "../debug/MonitorFlushedIndex"; -import {cliprogram} from "../common-libs/programOptions"; -import {DividendDAO, UDSource} from "./indexDAL/abstract/DividendDAO"; -import {HttpSource, HttpUD} from "../../modules/bma/lib/dtos"; -import {GenericDAO} from "./indexDAL/abstract/GenericDAO"; -import {MonitorExecutionTime} from "../debug/MonitorExecutionTime"; -import {LevelDBDividend} from "./indexDAL/leveldb/LevelDBDividend"; -import {LevelDBBindex} from "./indexDAL/leveldb/LevelDBBindex"; - -import {LevelUp} from "levelup"; -import {LevelDBBlockchain} from "./indexDAL/leveldb/LevelDBBlockchain"; -import {LevelDBSindex} from "./indexDAL/leveldb/LevelDBSindex"; -import {SqliteTransactions} from "./indexDAL/sqlite/SqliteTransactions"; -import {SqlitePeers} from "./indexDAL/sqlite/SqlitePeers"; -import {LevelDBWallet} from "./indexDAL/leveldb/LevelDBWallet"; -import {LevelDBCindex} from "./indexDAL/leveldb/LevelDBCindex"; -import {LevelDBIindex} from "./indexDAL/leveldb/LevelDBIindex"; -import {LevelDBMindex} from "./indexDAL/leveldb/LevelDBMindex"; -import {ConfDAO} from "./indexDAL/abstract/ConfDAO"; -import {ServerDAO} from "./server-dao"; +import { TransactionDTO } from "../dto/TransactionDTO"; +import { CertDAL, DBCert } from "./sqliteDAL/CertDAL"; +import { DBBlock } from "../db/DBBlock"; +import { DBMembership, MembershipDAL } from "./sqliteDAL/MembershipDAL"; +import { MerkleDTO } from "../dto/MerkleDTO"; +import { CommonConstants } from "../common-libs/constants"; +import { PowDAL } from "./fileDALs/PowDAL"; +import { Initiable } from "./sqliteDAL/Initiable"; +import { MetaDAL } from "./sqliteDAL/MetaDAL"; +import { DataErrors } from "../common-libs/errors"; +import { BasicRevocableIdentity, IdentityDTO } from "../dto/IdentityDTO"; +import { FileSystem } from "../system/directory"; +import { Wot } from "../../../neon/lib"; +import { IIndexDAO } from "./indexDAL/abstract/IIndexDAO"; +import { BIndexDAO } from "./indexDAL/abstract/BIndexDAO"; +import { MIndexDAO } from "./indexDAL/abstract/MIndexDAO"; +import { SIndexDAO } from "./indexDAL/abstract/SIndexDAO"; +import { CIndexDAO } from "./indexDAL/abstract/CIndexDAO"; +import { IdentityForRequirements } from "../../service/BlockchainService"; +import { BlockchainDAO } from "./indexDAL/abstract/BlockchainDAO"; +import { TxsDAO } from "./indexDAL/abstract/TxsDAO"; +import { WalletDAO } from "./indexDAL/abstract/WalletDAO"; +import { PeerDAO } from "./indexDAL/abstract/PeerDAO"; +import { DBTx } from "../db/DBTx"; +import { DBWallet } from "../db/DBWallet"; +import { Tristamp } from "../common/Tristamp"; +import { CFSCore } from "./fileDALs/CFSCore"; +import { Underscore } from "../common-libs/underscore"; +import { DBPeer } from "../db/DBPeer"; +import { MonitorFlushedIndex } from "../debug/MonitorFlushedIndex"; +import { cliprogram } from "../common-libs/programOptions"; +import { DividendDAO, UDSource } from "./indexDAL/abstract/DividendDAO"; +import { HttpSource, HttpUD } from "../../modules/bma/lib/dtos"; +import { GenericDAO } from "./indexDAL/abstract/GenericDAO"; +import { MonitorExecutionTime } from "../debug/MonitorExecutionTime"; +import { LevelDBDividend } from "./indexDAL/leveldb/LevelDBDividend"; +import { LevelDBBindex } from "./indexDAL/leveldb/LevelDBBindex"; + +import { LevelUp } from "levelup"; +import { LevelDBBlockchain } from "./indexDAL/leveldb/LevelDBBlockchain"; +import { LevelDBSindex } from "./indexDAL/leveldb/LevelDBSindex"; +import { SqliteTransactions } from "./indexDAL/sqlite/SqliteTransactions"; +import { SqlitePeers } from "./indexDAL/sqlite/SqlitePeers"; +import { LevelDBWallet } from "./indexDAL/leveldb/LevelDBWallet"; +import { LevelDBCindex } from "./indexDAL/leveldb/LevelDBCindex"; +import { LevelDBIindex } from "./indexDAL/leveldb/LevelDBIindex"; +import { LevelDBMindex } from "./indexDAL/leveldb/LevelDBMindex"; +import { ConfDAO } from "./indexDAL/abstract/ConfDAO"; +import { ServerDAO } from "./server-dao"; const readline = require("readline"); const indexer = require("../indexer").Indexer; @@ -150,7 +150,8 @@ export class FileDAL implements ServerDAO { this.powDAL = new PowDAL(this.rootPath, params.fs); this.confDAL = new ConfDAL(this.rootPath, params.fs); this.metaDAL = new (require("./sqliteDAL/MetaDAL").MetaDAL)( - this.sqliteDriver, getSqliteDB + this.sqliteDriver, + getSqliteDB ); this.idtyDAL = new (require("./sqliteDAL/IdentityDAL").IdentityDAL)( this.sqliteDriver @@ -1357,26 +1358,26 @@ export class FileDAL implements ServerDAO { * @private */ private async mapToDBTxs( - txs: TransactionDTO[], - block_number: number, - medianTime: number + txs: TransactionDTO[], + block_number: number, + medianTime: number ): Promise<DBTx[]> { return Promise.all( - txs.map(async (tx) => { - const sp = tx.blockstamp.split("-", 2); - const basedBlock = (await this.getAbsoluteBlockByNumberAndHash( - parseInt(sp[0]), - sp[1] - )) as DBBlock; - tx.blockstampTime = basedBlock.medianTime; - const txEntity = TransactionDTO.fromJSONObject(tx); - if (!txEntity.hash) txEntity.computeAllHashes(); - const dbTx = DBTx.fromTransactionDTO(txEntity); - dbTx.written = true; - dbTx.block_number = block_number; - dbTx.time = medianTime; - return dbTx; - }) + txs.map(async (tx) => { + const sp = tx.blockstamp.split("-", 2); + const basedBlock = (await this.getAbsoluteBlockByNumberAndHash( + parseInt(sp[0]), + sp[1] + )) as DBBlock; + tx.blockstampTime = basedBlock.medianTime; + const txEntity = TransactionDTO.fromJSONObject(tx); + if (!txEntity.hash) txEntity.computeAllHashes(); + const dbTx = DBTx.fromTransactionDTO(txEntity); + dbTx.written = true; + dbTx.block_number = block_number; + dbTx.time = medianTime; + return dbTx; + }) ); } @@ -1392,9 +1393,9 @@ export class FileDAL implements ServerDAO { } async insertTxsInFiles( - txs: TransactionDTO[], - block_number: number, - medianTime: number + txs: TransactionDTO[], + block_number: number, + medianTime: number ): Promise<DBTx[]> { if (!txs.length) return []; const dbTxs = await this.mapToDBTxs(txs, block_number, medianTime); diff --git a/app/lib/dal/indexDAL/sqlite/SqliteTable.ts b/app/lib/dal/indexDAL/sqlite/SqliteTable.ts index 52aa803f9060d41eaf8a0b73bbe2170e47d694b8..8923a6bafaa44e74470709f2b2b836c9b6d3b101 100644 --- a/app/lib/dal/indexDAL/sqlite/SqliteTable.ts +++ b/app/lib/dal/indexDAL/sqlite/SqliteTable.ts @@ -65,7 +65,7 @@ export class SqliteTable<T> { * Allow to migrate the table */ generateUpgradeSql(): string { - return ''; + return ""; } generateCreateIndexes() { @@ -204,7 +204,10 @@ export class SqliteTable<T> { async countBy(fieldName: keyof T, fieldValue: any): Promise<number> { return (( - await this.driver.sqlRead(`SELECT COUNT(*) as max FROM ${this.name} WHERE ${fieldName} = ?`, [fieldValue]) + await this.driver.sqlRead( + `SELECT COUNT(*) as max FROM ${this.name} WHERE ${fieldName} = ?`, + [fieldValue] + ) )[0] as any).max; } diff --git a/app/lib/dal/indexDAL/sqlite/SqliteTransactions.ts b/app/lib/dal/indexDAL/sqlite/SqliteTransactions.ts index b8846d7048c2b8b7ca93f619f8d83727f7b5342b..3c28fa64d2a50f458ccd1460bbdd4a2f117cb5c1 100644 --- a/app/lib/dal/indexDAL/sqlite/SqliteTransactions.ts +++ b/app/lib/dal/indexDAL/sqlite/SqliteTransactions.ts @@ -298,7 +298,7 @@ export class SqliteTransactions extends SqliteTable<DBTx> implements TxsDAO { // Delete by slice of 500 items (because SQLite IN operator is limited) while (i < hashArray.length - 1) { const slice = hashArray.slice(i, i + 500); - await this.driver.sqlWrite(`DELETE FROM txs WHERE hash IN (${slice.map(_ => '?')})`, slice); + await this.driver.sqlWrite(`DELETE FROM txs WHERE hash IN (${slice.map(_ => '?').join(', ')})`, slice); i += 500; } } diff --git a/app/lib/dal/sqliteDAL/MetaDAL.ts b/app/lib/dal/sqliteDAL/MetaDAL.ts index 4f4672c8d29e53362701289cb6a12ac156c4d0f6..ecb5c7a573bca8ddf2244a442d60738cea0c5ed1 100644 --- a/app/lib/dal/sqliteDAL/MetaDAL.ts +++ b/app/lib/dal/sqliteDAL/MetaDAL.ts @@ -16,10 +16,10 @@ import { SQLiteDriver } from "../drivers/SQLiteDriver"; import { ConfDTO } from "../../dto/ConfDTO"; import { TransactionDTO } from "../../dto/TransactionDTO"; import { IdentityDAL } from "./IdentityDAL"; -import {SqliteTransactions} from "../indexDAL/sqlite/SqliteTransactions"; -import {Directory} from "../../system/directory"; +import { SqliteTransactions } from "../indexDAL/sqlite/SqliteTransactions"; +import { Directory } from "../../system/directory"; -const constants = require('../../constants'); +const constants = require("../../constants"); const logger = require("../../logger").NewLogger("metaDAL"); export interface DBMeta { @@ -30,8 +30,10 @@ export interface DBMeta { export class MetaDAL extends AbstractSQLite<DBMeta> { driverCopy: SQLiteDriver; - constructor(driver: SQLiteDriver, - private getSqliteDB: (dbName: string) => Promise<SQLiteDriver>) { + constructor( + driver: SQLiteDriver, + private getSqliteDB: (dbName: string) => Promise<SQLiteDriver> + ) { super( driver, "meta", @@ -193,20 +195,18 @@ export class MetaDAL extends AbstractSQLite<DBMeta> { 25: async () => {}, // Drop old table 'txs' (replaced by a file 'txs.db') - 26: async() => { - await this.exec("BEGIN;" + - "DROP TABLE IF EXISTS txs;" + - "COMMIT;") + 26: async () => { + await this.exec("BEGIN;" + "DROP TABLE IF EXISTS txs;" + "COMMIT;"); }, // Add columns 'issuer' and 'recipient' in transaction table - see issue #1442 - 27: async() => { + 27: async () => { const txsDriver = await this.getSqliteDB("txs.db"); const txsDAL = new MetaDAL(txsDriver, this.getSqliteDB); // Drop unused indices await txsDAL.exec( - "BEGIN;" + + "BEGIN;" + "DROP INDEX IF EXISTS idx_txs_locktime;" + "DROP INDEX IF EXISTS idx_txs_version;" + "DROP INDEX IF EXISTS idx_txs_currency;" + @@ -224,17 +224,16 @@ export class MetaDAL extends AbstractSQLite<DBMeta> { try { await txsDAL.exec( "BEGIN;" + - "ALTER TABLE txs ADD COLUMN issuer VARCHAR(50) NULL;" + - "ALTER TABLE txs ADD COLUMN recipient VARCHAR(50) NULL;" + - "UOPDATE txs SET issuer = SUBSTR(issuers, 2, LENGTH(issuers) - 4) WHERE issuer IS NULL AND issuers NOT LIKE '%,%';" + - "UOPDATE txs SET recipient = SUBSTR(recipients, 2, LENGTH(recipients) - 4) WHERE recipient IS NULL AND recipients NOT LIKE '%,%';" + - "COMMIT;" + "ALTER TABLE txs ADD COLUMN issuer VARCHAR(50) NULL;" + + "ALTER TABLE txs ADD COLUMN recipient VARCHAR(50) NULL;" + + "UOPDATE txs SET issuer = SUBSTR(issuers, 2, LENGTH(issuers) - 4) WHERE issuer IS NULL AND issuers NOT LIKE '%,%';" + + "UOPDATE txs SET recipient = SUBSTR(recipients, 2, LENGTH(recipients) - 4) WHERE recipient IS NULL AND recipients NOT LIKE '%,%';" + + "COMMIT;" ); - } - catch(err) { + } catch (err) { // Silent: if column already exists } - } + }, }; async init() { @@ -271,7 +270,11 @@ export class MetaDAL extends AbstractSQLite<DBMeta> { async upgradeDatabase(conf: ConfDTO) { let version = await this.getVersion(); while (this.migrations[version]) { - logger.trace(`Upgrade database... (patch ${version}/${constants.CURRENT_DB_VERSION - 1})`); + logger.trace( + `Upgrade database... (patch ${version}/${ + constants.CURRENT_DB_VERSION - 1 + })` + ); await this.executeMigration(this.migrations[version], conf); // Version increment @@ -286,7 +289,7 @@ export class MetaDAL extends AbstractSQLite<DBMeta> { async getVersion() { try { - const {version} = await this.getRow(); + const { version } = await this.getRow(); return version; } catch (e) { // Insert zero, as first version diff --git a/app/lib/db/DBTx.ts b/app/lib/db/DBTx.ts index bcb1954decbbc06e7639d84be1a177a7ae96a719..b238ac831cdf85433e5db66cf6997cc010249f30 100644 --- a/app/lib/db/DBTx.ts +++ b/app/lib/db/DBTx.ts @@ -48,11 +48,12 @@ export class DBTx { dbTx.output_amount = tx.output_amount; // Computed columns (unique issuer and/or recipient) - dbTx.issuer = (dbTx.issuers.length === 1) ? dbTx.issuers[0] : null; - const recipients = !dbTx.issuer ? dbTx.recipients : dbTx.recipients.filter(r => r !== dbTx.issuer); - dbTx.recipient = (recipients.length === 1) ? recipients[0] : null; + dbTx.issuer = dbTx.issuers.length === 1 ? dbTx.issuers[0] : null; + const recipients = !dbTx.issuer + ? dbTx.recipients + : dbTx.recipients.filter((r) => r !== dbTx.issuer); + dbTx.recipient = recipients.length === 1 ? recipients[0] : null; return dbTx; } - } diff --git a/app/lib/dto/TransactionDTO.ts b/app/lib/dto/TransactionDTO.ts index 618488046ac509dcd55666a6fe5784213f96e506..e107470334ad275bfbb5132273e8d8daef2d1cd4 100644 --- a/app/lib/dto/TransactionDTO.ts +++ b/app/lib/dto/TransactionDTO.ts @@ -14,7 +14,7 @@ import { hashf } from "../common"; import { Cloneable } from "./Cloneable"; import { verify } from "../../../neon/lib"; -import {CommonConstants} from "../common-libs/constants"; +import { CommonConstants } from "../common-libs/constants"; export interface BaseDTO { base: number; @@ -168,10 +168,15 @@ export class TransactionDTO implements Cloneable { return this.outputs.reduce((res, output) => { let match: any; const recipients: string[] = []; - while (output && (match = CommonConstants.TRANSACTION.OUTPUT_CONDITION_SIG_PUBKEY.exec(output)) !== null) { + while ( + output && + (match = CommonConstants.TRANSACTION.OUTPUT_CONDITION_SIG_PUBKEY.exec( + output + )) !== null + ) { const pub = match[1] as string; if (!res.includes(pub) && !recipients.includes(pub)) { - recipients.push(pub) + recipients.push(pub); } output = output.substring(match.index + match[0].length); } diff --git a/app/modules/crawler/lib/sync/RemoteSynchronizer.ts b/app/modules/crawler/lib/sync/RemoteSynchronizer.ts index e00e9ef2f71cc73d66db9665ab045ca0165748cf..7c31a61d505bffeb004d6f3286681855e631ff00 100644 --- a/app/modules/crawler/lib/sync/RemoteSynchronizer.ts +++ b/app/modules/crawler/lib/sync/RemoteSynchronizer.ts @@ -150,7 +150,7 @@ export class RemoteSynchronizer extends AbstractSynchronizer { const host = access.host; const port = access.port; const path = access.path; - logger.info(`Connecting to address ${host}:${port}${path||''}...`); + logger.info(`Connecting to address ${host}:${port}${path || ""}...`); // If we know this is a WS2P connection, don't try BMA if (access.isWS2P !== true) { @@ -159,15 +159,15 @@ export class RemoteSynchronizer extends AbstractSynchronizer { PeerDTO.fromJSONObject({ endpoints: [ `BASIC_MERKLED_API ${host} ${port}` + - ((path && ' ' + path) || ''), + ((path && " " + path) || ""), ], }), 3000 ); peering = await contacter.getPeer(); api = new BMARemoteContacter(contacter); - endpoint = `BASIC_MERKLED_API ${host} ${port}` + - ((path && ' ' + path) || ''); + endpoint = + `BASIC_MERKLED_API ${host} ${port}` + ((path && " " + path) || ""); } catch (e) {} } @@ -176,7 +176,7 @@ export class RemoteSynchronizer extends AbstractSynchronizer { const pair = new Key(keypair.pub, keypair.sec); const connection = WS2PConnection.newConnectionToAddress( 1, - `ws://${host}:${port}${path || ''}`, + `ws://${host}:${port}${path || ""}`, new (class SyncMessageHandler implements WS2PMessageHandler { async answerToRequest( json: any,