From c7c8d9fe544539bb4715be7fe4bf7506f6756b8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Moreau?= <cem.moreau@gmail.com> Date: Fri, 4 May 2018 19:36:58 +0200 Subject: [PATCH] [enh] Remove SQL obsolete code --- app/lib/blockchain/DuniterBlockchain.ts | 2 +- app/lib/computation/QuickSync.ts | 2 +- app/lib/constants.ts | 4 +- app/lib/dal/fileDAL.ts | 13 +- app/lib/dal/indexDAL/abstract/TxsDAO.ts | 2 +- app/lib/dal/indexDAL/abstract/WalletDAO.ts | 2 +- app/lib/dal/indexDAL/loki/LokiTransactions.ts | 2 +- app/lib/dal/indexDAL/loki/LokiWallet.ts | 2 +- app/lib/dal/sqliteDAL/BlockDAL.ts | 170 ----------- app/lib/dal/sqliteDAL/MetaDAL.ts | 76 ++++- app/lib/dal/sqliteDAL/TxsDAL.ts | 286 ------------------ app/lib/dal/sqliteDAL/WalletDAL.ts | 69 ----- app/lib/db/DBTx.ts | 60 ++++ app/lib/db/DBWallet.ts | 4 + app/lib/indexer.ts | 2 +- app/lib/rules/global_rules.ts | 2 +- .../bma/lib/controllers/transactions.ts | 2 +- app/service/TransactionsService.ts | 3 +- 18 files changed, 145 insertions(+), 558 deletions(-) delete mode 100644 app/lib/dal/sqliteDAL/BlockDAL.ts delete mode 100644 app/lib/dal/sqliteDAL/TxsDAL.ts delete mode 100644 app/lib/dal/sqliteDAL/WalletDAL.ts create mode 100644 app/lib/db/DBTx.ts create mode 100644 app/lib/db/DBWallet.ts diff --git a/app/lib/blockchain/DuniterBlockchain.ts b/app/lib/blockchain/DuniterBlockchain.ts index 1c0402613..92b419a62 100644 --- a/app/lib/blockchain/DuniterBlockchain.ts +++ b/app/lib/blockchain/DuniterBlockchain.ts @@ -24,9 +24,9 @@ import {MembershipDTO} from "../dto/MembershipDTO" import {TransactionDTO} from "../dto/TransactionDTO" import {CommonConstants} from "../common-libs/constants" import {FileDAL} from "../dal/fileDAL" -import {DBTx} from "../dal/sqliteDAL/TxsDAL" import {DataErrors} from "../common-libs/errors" import {NewLogger} from "../logger" +import {DBTx} from "../db/DBTx" const _ = require('underscore') diff --git a/app/lib/computation/QuickSync.ts b/app/lib/computation/QuickSync.ts index f2f94a5ba..5ac8d4e56 100644 --- a/app/lib/computation/QuickSync.ts +++ b/app/lib/computation/QuickSync.ts @@ -18,7 +18,7 @@ import {AccountsGarbagingDAL, FullSindexEntry, Indexer} from "../indexer"; import {CurrencyConfDTO} from "../dto/ConfDTO"; import {FileDAL} from "../dal/fileDAL" import {DBBlock} from "../db/DBBlock" -import {DBTx} from "../dal/sqliteDAL/TxsDAL" +import {DBTx} from "../db/DBTx" const _ = require('underscore') const constants = require('../constants') diff --git a/app/lib/constants.ts b/app/lib/constants.ts index 5b9f76d72..bc605076a 100644 --- a/app/lib/constants.ts +++ b/app/lib/constants.ts @@ -14,7 +14,7 @@ "use strict"; import {CommonConstants} from "./common-libs/constants" import {OtherConstants} from "./other_constants" -import { ProverConstants } from '../modules/prover/lib/constants'; +import {ProverConstants} from '../modules/prover/lib/constants'; const UDID2 = "udid2;c;([A-Z-]*);([A-Z-]*);(\\d{4}-\\d{2}-\\d{2});(e\\+\\d{2}\\.\\d{2}(\\+|-)\\d{3}\\.\\d{2});(\\d+)(;?)"; const PUBKEY = CommonConstants.FORMATS.PUBKEY @@ -185,8 +185,6 @@ module.exports = { SANDBOX_SIZE_CERTIFICATIONS: 12, SANDBOX_SIZE_MEMBERSHIPS: 5000, - CURRENT_BLOCK_CACHE_DURATION: 10 * 1000, // 30 seconds - // With `logs` command, the number of tail lines to show NB_INITIAL_LINES_TO_SHOW: 100 }; diff --git a/app/lib/dal/fileDAL.ts b/app/lib/dal/fileDAL.ts index 8902b0707..c0ea81909 100644 --- a/app/lib/dal/fileDAL.ts +++ b/app/lib/dal/fileDAL.ts @@ -30,8 +30,6 @@ import { import {DBPeer} from "./sqliteDAL/PeerDAL" import {TransactionDTO} from "../dto/TransactionDTO" import {CertDAL, DBCert} from "./sqliteDAL/CertDAL" -import {DBWallet} from "./sqliteDAL/WalletDAL" -import {DBTx, TxsDAL} from "./sqliteDAL/TxsDAL" import {DBBlock} from "../db/DBBlock" import {DBMembership, MembershipDAL} from "./sqliteDAL/MembershipDAL" import {MerkleDTO} from "../dto/MerkleDTO" @@ -41,7 +39,6 @@ import {Initiable} from "./sqliteDAL/Initiable" import {MetaDAL} from "./sqliteDAL/MetaDAL" import {DataErrors} from "../common-libs/errors" import {BasicRevocableIdentity, IdentityDTO} from "../dto/IdentityDTO" -import {BlockDAL} from "./sqliteDAL/BlockDAL" import {FileSystem} from "../system/directory" import {WoTBInstance} from "../wot" import {IIndexDAO} from "./indexDAL/abstract/IIndexDAO" @@ -66,6 +63,8 @@ import {WalletDAO} from "./indexDAL/abstract/WalletDAO" import {LokiWallet} from "./indexDAL/loki/LokiWallet" import {PeerDAO} from "./indexDAL/abstract/PeerDAO" import {LokiPeer} from "./indexDAL/loki/LokiPeer" +import {DBTx} from "../db/DBTx" +import {DBWallet} from "../db/DBWallet" const fs = require('fs') const path = require('path') @@ -96,10 +95,6 @@ export class FileDAL { confDAL:ConfDAL statDAL:StatDAL - // DALs to be removed - fakeBlockDAL:BlockDAL - fakeTxsDAL:TxsDAL - // SQLite DALs metaDAL:MetaDAL idtyDAL:IdentityDAL @@ -132,9 +127,7 @@ export class FileDAL { 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); - this.fakeBlockDAL = new (require('./sqliteDAL/BlockDAL').BlockDAL)(this.sqliteDriver); this.blockDAL = new LokiBlockchain(this.loki.getLokiInstance()) - this.fakeTxsDAL = new (require('./sqliteDAL/TxsDAL').TxsDAL)(this.sqliteDriver); this.txsDAL = new LokiTransactions(this.loki.getLokiInstance()) this.statDAL = new StatDAL(this.rootPath, params.fs) this.idtyDAL = new (require('./sqliteDAL/IdentityDAL').IdentityDAL)(this.sqliteDriver); @@ -152,8 +145,6 @@ export class FileDAL { 'powDAL': this.powDAL, 'metaDAL': this.metaDAL, 'blockDAL': this.blockDAL, - 'fakeBlockDAL': this.fakeBlockDAL, - 'fakeTxsDAL': this.fakeTxsDAL, 'certDAL': this.certDAL, 'msDAL': this.msDAL, 'idtyDAL': this.idtyDAL, diff --git a/app/lib/dal/indexDAL/abstract/TxsDAO.ts b/app/lib/dal/indexDAL/abstract/TxsDAO.ts index f4189f592..fe425eb52 100644 --- a/app/lib/dal/indexDAL/abstract/TxsDAO.ts +++ b/app/lib/dal/indexDAL/abstract/TxsDAO.ts @@ -1,7 +1,7 @@ import {GenericDAO} from "./GenericDAO" -import {DBTx} from "../../sqliteDAL/TxsDAL" import {TransactionDTO} from "../../../dto/TransactionDTO" import {SandBox} from "../../sqliteDAL/SandBox" +import {DBTx} from "../../../db/DBTx" export interface TxsDAO extends GenericDAO<DBTx> { diff --git a/app/lib/dal/indexDAL/abstract/WalletDAO.ts b/app/lib/dal/indexDAL/abstract/WalletDAO.ts index 4e9a34ff8..4774e6943 100644 --- a/app/lib/dal/indexDAL/abstract/WalletDAO.ts +++ b/app/lib/dal/indexDAL/abstract/WalletDAO.ts @@ -1,5 +1,5 @@ import {Initiable} from "../../sqliteDAL/Initiable" -import {DBWallet} from "../../sqliteDAL/WalletDAL" +import {DBWallet} from "../../../db/DBWallet" export interface WalletDAO extends Initiable { diff --git a/app/lib/dal/indexDAL/loki/LokiTransactions.ts b/app/lib/dal/indexDAL/loki/LokiTransactions.ts index 1987b4a71..ea8a09ecf 100644 --- a/app/lib/dal/indexDAL/loki/LokiTransactions.ts +++ b/app/lib/dal/indexDAL/loki/LokiTransactions.ts @@ -1,8 +1,8 @@ import {LokiIndex} from "./LokiIndex" -import {DBTx} from "../../sqliteDAL/TxsDAL" import {TxsDAO} from "../abstract/TxsDAO" import {SandBox} from "../../sqliteDAL/SandBox" import {TransactionDTO} from "../../../dto/TransactionDTO" +import {DBTx} from "../../../db/DBTx" const _ = require('underscore') const moment = require('moment') diff --git a/app/lib/dal/indexDAL/loki/LokiWallet.ts b/app/lib/dal/indexDAL/loki/LokiWallet.ts index cd0e3c7a3..caf8d3134 100644 --- a/app/lib/dal/indexDAL/loki/LokiWallet.ts +++ b/app/lib/dal/indexDAL/loki/LokiWallet.ts @@ -1,6 +1,6 @@ import {WalletDAO} from "../abstract/WalletDAO" -import {DBWallet} from "../../sqliteDAL/WalletDAL" import {LokiCollectionManager} from "./LokiCollectionManager" +import {DBWallet} from "../../../db/DBWallet" export class LokiWallet extends LokiCollectionManager<DBWallet> implements WalletDAO { diff --git a/app/lib/dal/sqliteDAL/BlockDAL.ts b/app/lib/dal/sqliteDAL/BlockDAL.ts deleted file mode 100644 index 9909bb207..000000000 --- a/app/lib/dal/sqliteDAL/BlockDAL.ts +++ /dev/null @@ -1,170 +0,0 @@ -// Source file from duniter: Crypto-currency software to manage libre currency such as Ğ1 -// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. - -import {AbstractSQLite} from "./AbstractSQLite" -import {SQLiteDriver} from "../drivers/SQLiteDriver" -import {DBBlock} from "../../db/DBBlock" - -const constants = require('../../constants'); - -const IS_FORK = true; -const IS_NOT_FORK = false; - -export class BlockDAL extends AbstractSQLite<DBBlock> { - - private current: DBBlock|null - - constructor(driver:SQLiteDriver) { - super( - driver, - 'block', - // PK fields - ['number','hash'], - // Fields - ['fork', 'hash', 'inner_hash', 'signature', 'currency', 'issuer', 'issuersCount', 'issuersFrame', 'issuersFrameVar', 'parameters', 'previousHash', 'previousIssuer', 'version', 'membersCount', 'monetaryMass', 'UDTime', 'medianTime', 'dividend', 'unitbase', 'time', 'powMin', 'number', 'nonce', 'transactions', 'certifications', 'identities', 'joiners', 'actives', 'leavers', 'revoked', 'excluded', 'len'], - // Arrays - ['identities','certifications','actives','revoked','excluded','leavers','joiners','transactions'], - // Booleans - ['wrong'], - // BigIntegers - ['monetaryMass'], - // Transient - [] - ) - - /** - * Periodically cleans the current block cache. - * It seems the cache is not always correct and may stuck the node, so it is preferable to reset it periodically. - */ - setInterval(this.cleanCache, constants.CURRENT_BLOCK_CACHE_DURATION); - } - - async init() { - await this.exec('BEGIN;' + - 'CREATE TABLE IF NOT EXISTS ' + this.table + ' (' + - 'fork BOOLEAN NOT NULL,' + - 'hash VARCHAR(64) NOT NULL,' + - 'inner_hash VARCHAR(64) NOT NULL,' + - 'signature VARCHAR(100) NOT NULL,' + - 'currency VARCHAR(50) NOT NULL,' + - 'issuer VARCHAR(50) NOT NULL,' + - 'parameters VARCHAR(255),' + - 'previousHash VARCHAR(64),' + - 'previousIssuer VARCHAR(50),' + - 'version INTEGER NOT NULL,' + - 'membersCount INTEGER NOT NULL,' + - 'monetaryMass VARCHAR(100) DEFAULT \'0\',' + - 'UDTime DATETIME,' + - 'medianTime DATETIME NOT NULL,' + - 'dividend INTEGER DEFAULT \'0\',' + - 'unitbase INTEGER NULL,' + - 'time DATETIME NOT NULL,' + - 'powMin INTEGER NOT NULL,' + - 'number INTEGER NOT NULL,' + - 'nonce INTEGER NOT NULL,' + - 'transactions TEXT,' + - 'certifications TEXT,' + - 'identities TEXT,' + - 'joiners TEXT,' + - 'actives TEXT,' + - 'leavers TEXT,' + - 'revoked TEXT,' + - 'excluded TEXT,' + - 'created DATETIME DEFAULT NULL,' + - 'updated DATETIME DEFAULT NULL,' + - 'PRIMARY KEY (number,hash)' + - ');' + - 'CREATE INDEX IF NOT EXISTS idx_block_hash ON block (hash);' + - 'CREATE INDEX IF NOT EXISTS idx_block_fork ON block (fork);' + - 'COMMIT;') - } - - cleanCache() { - this.current = null - } - - async getCurrent() { - if (!this.current) { - this.current = (await this.query('SELECT * FROM block WHERE NOT fork ORDER BY number DESC LIMIT 1'))[0]; - } - return this.current - } - - async getBlock(number:string | number): Promise<DBBlock|null> { - return (await this.query('SELECT * FROM block WHERE number = ? and NOT fork', [parseInt(String(number))]))[0]; - } - - async getAbsoluteBlock(number:number, hash:string): Promise<DBBlock|null> { - return (await this.query('SELECT * FROM block WHERE number = ? and hash = ?', [number, hash]))[0]; - } - - getBlocks(start:number, end:number) { - return this.query('SELECT * FROM block WHERE number BETWEEN ? and ? and NOT fork ORDER BY number ASC', [start, end]); - } - - async lastBlockOfIssuer(issuer:string) { - return (await this.query('SELECT * FROM block WHERE issuer = ? and NOT fork ORDER BY number DESC LIMIT 1', [issuer]))[0] - } - - async getCountOfBlocksIssuedBy(issuer:string) { - let res: any = await this.query('SELECT COUNT(*) as quantity FROM block WHERE issuer = ? and NOT fork', [issuer]); - return res[0].quantity; - } - - getPotentialForkBlocks(numberStart:number, medianTimeStart:number, maxNumber:number) { - return this.query('SELECT * FROM block WHERE fork AND number >= ? AND number <= ? AND medianTime >= ? ORDER BY number DESC', [numberStart, maxNumber, medianTimeStart]); - } - - getPotentialRoots() { - return this.query('SELECT * FROM block WHERE fork AND number = ?', [0]) - } - - async saveBunch(blocks:DBBlock[]) { - let queries = "INSERT INTO block (" + this.fields.join(',') + ") VALUES "; - for (let i = 0, len = blocks.length; i < len; i++) { - let block = blocks[i]; - queries += this.toInsertValues(block); - if (i + 1 < len) { - queries += ",\n"; - } - } - await this.exec(queries); - this.cleanCache(); - } - - async saveBlock(block:DBBlock) { - let saved = await this.saveBlockAs(block, IS_NOT_FORK); - if (!this.current || this.current.number < block.number) { - this.current = block; - } - return saved; - } - - saveSideBlock(block:DBBlock) { - return this.saveBlockAs(block, IS_FORK) - } - - private async saveBlockAs(block:DBBlock, fork:boolean) { - block.fork = fork; - return await this.saveEntity(block); - } - - async setSideBlock(number:number, previousBlock:DBBlock|null) { - await this.query('UPDATE block SET fork = ? WHERE number = ?', [true, number]); - this.current = previousBlock; - } - - getNextForkBlocks(number:number, hash:string) { - return this.query('SELECT * FROM block WHERE fork AND number = ? AND previousHash like ? ORDER BY number', [number + 1, hash]); - } -} diff --git a/app/lib/dal/sqliteDAL/MetaDAL.ts b/app/lib/dal/sqliteDAL/MetaDAL.ts index 26d27b93e..2ca460cd8 100644 --- a/app/lib/dal/sqliteDAL/MetaDAL.ts +++ b/app/lib/dal/sqliteDAL/MetaDAL.ts @@ -17,16 +17,12 @@ import {ConfDTO} from "../../dto/ConfDTO" import {SindexEntry} from "../../indexer" import {hashf} from "../../common" import {TransactionDTO} from "../../dto/TransactionDTO" -import {BlockDAL} from "./BlockDAL" import {IdentityDAL} from "./IdentityDAL" import {SIndexDAL} from "./index/SIndexDAL" -import {WalletDAL} from "./WalletDAL" -import {MIndexDAL} from "./index/MIndexDAL" import {DBBlock} from "../../db/DBBlock" import {IdentityDTO} from "../../dto/IdentityDTO" import {rawer} from "../../common-libs/index" import {CommonConstants} from "../../common-libs/constants" -import {TxsDAL} from "./TxsDAL" const _ = require('underscore') const logger = require('../../logger').NewLogger('metaDAL'); @@ -66,7 +62,71 @@ export class MetaDAL extends AbstractSQLite<DBMeta> { private migrations:any = { // Test - 0: 'BEGIN; COMMIT;', + 0: 'BEGIN;' + + + // This table was initially created by BlockDAL, but now it has been removed so we keep it here + // to keep the unit tests work + 'CREATE TABLE IF NOT EXISTS block (' + + 'fork BOOLEAN NOT NULL,' + + 'hash VARCHAR(64) NOT NULL,' + + 'inner_hash VARCHAR(64) NOT NULL,' + + 'signature VARCHAR(100) NOT NULL,' + + 'currency VARCHAR(50) NOT NULL,' + + 'issuer VARCHAR(50) NOT NULL,' + + 'parameters VARCHAR(255),' + + 'previousHash VARCHAR(64),' + + 'previousIssuer VARCHAR(50),' + + 'version INTEGER NOT NULL,' + + 'membersCount INTEGER NOT NULL,' + + 'monetaryMass VARCHAR(100) DEFAULT \'0\',' + + 'UDTime DATETIME,' + + 'medianTime DATETIME NOT NULL,' + + 'dividend INTEGER DEFAULT \'0\',' + + 'unitbase INTEGER NULL,' + + 'time DATETIME NOT NULL,' + + 'powMin INTEGER NOT NULL,' + + 'number INTEGER NOT NULL,' + + 'nonce INTEGER NOT NULL,' + + 'transactions TEXT,' + + 'certifications TEXT,' + + 'identities TEXT,' + + 'joiners TEXT,' + + 'actives TEXT,' + + 'leavers TEXT,' + + 'revoked TEXT,' + + 'excluded TEXT,' + + 'created DATETIME DEFAULT NULL,' + + 'updated DATETIME DEFAULT NULL,' + + 'PRIMARY KEY (number,hash)' + + ');' + + 'CREATE INDEX IF NOT EXISTS idx_block_hash ON block (hash);' + + 'CREATE INDEX IF NOT EXISTS idx_block_fork ON block (fork);' + + + // Same, but for Transactions + 'CREATE TABLE IF NOT EXISTS txs (' + + 'hash CHAR(64) NOT NULL,' + + 'block_number INTEGER,' + + 'locktime INTEGER NOT NULL,' + + 'version INTEGER NOT NULL,' + + 'currency VARCHAR(50) NOT NULL,' + + 'comment VARCHAR(255) NOT NULL,' + + 'time DATETIME,' + + 'inputs TEXT NOT NULL,' + + 'unlocks TEXT NOT NULL,' + + 'outputs TEXT NOT NULL,' + + 'issuers TEXT NOT NULL,' + + 'signatures TEXT NOT NULL,' + + 'recipients TEXT NOT NULL,' + + 'written BOOLEAN NOT NULL,' + + 'removed BOOLEAN NOT NULL,' + + 'PRIMARY KEY (hash)' + + ');' + + 'CREATE INDEX IF NOT EXISTS idx_txs_issuers ON txs (issuers);' + + 'CREATE INDEX IF NOT EXISTS idx_txs_written ON txs (written);' + + 'CREATE INDEX IF NOT EXISTS idx_txs_removed ON txs (removed);' + + 'CREATE INDEX IF NOT EXISTS idx_txs_hash ON txs (hash);' + + + 'COMMIT;', // Test 1: 'BEGIN;' + @@ -105,7 +165,7 @@ export class MetaDAL extends AbstractSQLite<DBMeta> { 'ALTER TABLE block ADD COLUMN issuersCount INTEGER NULL;' + 'COMMIT;', 12: async () => { - let blockDAL = new BlockDAL(this.driverCopy) + let blockDAL = new MetaDAL(this.driverCopy) await blockDAL.exec('ALTER TABLE block ADD COLUMN len INTEGER NULL;'); await blockDAL.exec('ALTER TABLE txs ADD COLUMN len INTEGER NULL;'); }, @@ -147,7 +207,7 @@ export class MetaDAL extends AbstractSQLite<DBMeta> { 16: async () => {}, 17: async () => { - let blockDAL = new BlockDAL(this.driverCopy) + let blockDAL:any = new MetaDAL(this.driverCopy) let sindexDAL = new SIndexDAL(this.driverCopy) const blocks = await blockDAL.query('SELECT * FROM block WHERE NOT fork'); type AmountPerKey = { @@ -336,7 +396,7 @@ export class MetaDAL extends AbstractSQLite<DBMeta> { * Wrong transaction storage */ 25: async () => { - const txsDAL = new TxsDAL(this.driverCopy) + const txsDAL:any = new MetaDAL(this.driverCopy) const wrongTXS = await txsDAL.query('SELECT * FROM txs WHERE outputs LIKE ? OR inputs LIKE ?', ['%amount%', '%amount%']) let i = 1 for (const tx of wrongTXS) { diff --git a/app/lib/dal/sqliteDAL/TxsDAL.ts b/app/lib/dal/sqliteDAL/TxsDAL.ts deleted file mode 100644 index 58b7c6167..000000000 --- a/app/lib/dal/sqliteDAL/TxsDAL.ts +++ /dev/null @@ -1,286 +0,0 @@ -// Source file from duniter: Crypto-currency software to manage libre currency such as Ğ1 -// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. - -import {AbstractSQLite} from "./AbstractSQLite" -import {SQLiteDriver} from "../drivers/SQLiteDriver" -import {TransactionDTO} from "../../dto/TransactionDTO" -import {SandBox} from "./SandBox" - -const _ = require('underscore'); -const moment = require('moment'); -const constants = require('../../constants'); - -export class DBTx { - hash: string - block_number: number | null - locktime: number - version: number - currency: string - comment: string - blockstamp: string - blockstampTime: number | null - time: number | null - inputs: string[] - unlocks: string[] - outputs: string[] - issuers: string[] - signatures: string[] - recipients: string[] - written: boolean - removed: boolean - received: number - output_base: number - output_amount: number - written_on: string - writtenOn: number - - static fromTransactionDTO(tx:TransactionDTO) { - const dbTx = new DBTx() - dbTx.hash = tx.hash - dbTx.locktime = tx.locktime - dbTx.version = tx.version - dbTx.currency = tx.currency - dbTx.blockstamp = tx.blockstamp - dbTx.blockstampTime = tx.blockstampTime - dbTx.comment = tx.comment || "" - dbTx.inputs = tx.inputs - dbTx.unlocks = tx.unlocks - dbTx.outputs = tx.outputs - dbTx.issuers = tx.issuers - dbTx.signatures = tx.signatures - dbTx.recipients = tx.outputsAsRecipients() - dbTx.written = false - dbTx.removed = false - dbTx.output_base = tx.output_base - dbTx.output_amount = tx.output_amount - return dbTx - } - - static setRecipients(txs:DBTx[]) { - // Each transaction must have a good "recipients" field for future searchs - txs.forEach((tx) => tx.recipients = DBTx.outputs2recipients(tx)) - } - - static outputs2recipients(tx:DBTx) { - return tx.outputs.map(function(out) { - const recipent = out.match('SIG\\((.*)\\)') - return (recipent && recipent[1]) || 'UNKNOWN' - }) - } -} - -export class TxsDAL extends AbstractSQLite<DBTx> { - - constructor(driver:SQLiteDriver) { - super( - driver, - 'txs', - // PK fields - ['hash'], - // Fields - [ - 'hash', - 'block_number', - 'version', - 'currency', - 'comment', - 'blockstamp', - 'blockstampTime', - 'locktime', - 'received', - 'time', - 'written', - 'removed', - 'inputs', - 'unlocks', - 'outputs', - 'issuers', - 'signatures', - 'recipients', - 'output_base', - 'output_amount' - ], - // Arrays - ['inputs','unlocks','outputs','issuers','signatures','recipients'], - // Booleans - ['written','removed'], - // BigIntegers - [], - // Transient - [] - ) - } - - async init() { - await this.exec('BEGIN;' + - 'CREATE TABLE IF NOT EXISTS ' + this.table + ' (' + - 'hash CHAR(64) NOT NULL,' + - 'block_number INTEGER,' + - 'locktime INTEGER NOT NULL,' + - 'version INTEGER NOT NULL,' + - 'currency VARCHAR(50) NOT NULL,' + - 'comment VARCHAR(255) NOT NULL,' + - 'time DATETIME,' + - 'inputs TEXT NOT NULL,' + - 'unlocks TEXT NOT NULL,' + - 'outputs TEXT NOT NULL,' + - 'issuers TEXT NOT NULL,' + - 'signatures TEXT NOT NULL,' + - 'recipients TEXT NOT NULL,' + - 'written BOOLEAN NOT NULL,' + - 'removed BOOLEAN NOT NULL,' + - 'PRIMARY KEY (hash)' + - ');' + - 'CREATE INDEX IF NOT EXISTS idx_txs_issuers ON txs (issuers);' + - 'CREATE INDEX IF NOT EXISTS idx_txs_written ON txs (written);' + - 'CREATE INDEX IF NOT EXISTS idx_txs_removed ON txs (removed);' + - 'CREATE INDEX IF NOT EXISTS idx_txs_hash ON txs (hash);' + - 'COMMIT;') - } - - getAllPending(versionMin:number): Promise<DBTx[]> { - return this.sqlFind({ - written: false, - removed: false, - version: { $gte: versionMin } - }) - } - - getTX(hash:string): Promise<DBTx> { - return this.sqlFindOne({ - hash: hash - }) - } - - async removeTX(hash:string) { - const tx = await this.sqlFindOne({ - hash: hash - }); - if (tx) { - tx.removed = true; - return this.saveEntity(tx); - } - return tx - } - - addLinked(tx:TransactionDTO, block_number:number, time:number) { - const dbTx = DBTx.fromTransactionDTO(tx) - dbTx.block_number = block_number - dbTx.time = time - dbTx.received = moment().unix() - dbTx.written = true - dbTx.removed = false - dbTx.hash = tx.getHash() - return this.saveEntity(dbTx) - } - - addPending(dbTx:DBTx) { - dbTx.received = moment().unix() - dbTx.written = false - dbTx.removed = false - return this.saveEntity(dbTx) - } - - getLinkedWithIssuer(pubkey:string): Promise<DBTx[]> { - return this.sqlFind({ - issuers: { $contains: pubkey }, - written: true - }) - } - - async getLinkedWithRecipient(pubkey:string) { - const rows = await this.sqlFind({ - recipients: { $contains: pubkey }, - written: true - }) - // Which does not contains the key as issuer - return _.filter(rows, (row:DBTx) => row.issuers.indexOf(pubkey) === -1); - } - - getPendingWithIssuer(pubkey:string) { - return this.sqlFind({ - issuers: { $contains: pubkey }, - written: false, - removed: false - }) - } - - getPendingWithRecipient(pubkey:string) { - return this.sqlFind({ - recipients: { $contains: pubkey }, - written: false, - removed: false - }) - } - - insertBatchOfTxs(txs:DBTx[]) { - // // Be sure the recipients field are correctly updated - DBTx.setRecipients(txs); - const queries = []; - const insert = this.getInsertHead(); - const values = txs.map((cert) => this.getInsertValue(cert)); - if (txs.length) { - queries.push(insert + '\n' + values.join(',\n') + ';'); - } - if (queries.length) { - this.exec(queries.join('\n')); - } - } - - trimExpiredNonWrittenTxs(limitTime:number) { - return this.exec("DELETE FROM txs WHERE NOT written AND blockstampTime <= " + limitTime) - } - - getTransactionByExtendedHash(hash:string) { - return this.query("SELECT * FROM txs WHERE hash = ? OR v4_hash = ? OR v5_hash = ?", [hash, hash, hash]) - } - - /************************** - * SANDBOX STUFF - */ - - getSandboxTxs() { - return this.query('SELECT * FROM sandbox_txs LIMIT ' + (this.sandbox.maxSize), []) - } - - sandbox:SandBox<{ issuers: string[], output_base:number, output_amount:number }> = new SandBox( - constants.SANDBOX_SIZE_TRANSACTIONS, - () => this.getSandboxTxs(), - (compared:{ issuers: string[], output_base:number, output_amount:number }, - reference:{ issuers: string[], output_base:number, output_amount:number } - ) => { - if (compared.output_base < reference.output_base) { - return -1; - } - else if (compared.output_base > reference.output_base) { - return 1; - } - else if (compared.output_amount > reference.output_amount) { - return -1; - } - else if (compared.output_amount < reference.output_amount) { - return 1; - } - else { - return 0; - } - }) - - getSandboxRoom() { - return this.sandbox.getSandboxRoom() - } - - setSandboxSize(maxSize:number) { - this.sandbox.maxSize = maxSize - } -} diff --git a/app/lib/dal/sqliteDAL/WalletDAL.ts b/app/lib/dal/sqliteDAL/WalletDAL.ts deleted file mode 100644 index 03644eac3..000000000 --- a/app/lib/dal/sqliteDAL/WalletDAL.ts +++ /dev/null @@ -1,69 +0,0 @@ -// Source file from duniter: Crypto-currency software to manage libre currency such as Ğ1 -// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. - -import {SQLiteDriver} from "../drivers/SQLiteDriver"; -import {AbstractSQLite} from "./AbstractSQLite"; - -export interface DBWallet { - conditions: string - balance: number -} - -/** - * Facility table saving the current state of a wallet. - * @param driver SQL driver for making SQL requests. - * @constructor - */ -export class WalletDAL extends AbstractSQLite<DBWallet> { - - constructor(driver:SQLiteDriver) { - super( - driver, - 'wallet', - // PK fields - ['conditions'], - // Fields - [ - 'conditions', - 'balance' - ], - // Arrays - [], - // Booleans - [], - // BigIntegers - ['monetaryMass'], - // Transient - [] - ) - } - - async init() { - await this.exec('BEGIN;' + - 'CREATE TABLE IF NOT EXISTS ' + this.table + ' (' + - 'conditions TEXT NOT NULL,' + - 'balance INTEGER NOT NULL,' + - 'PRIMARY KEY (conditions)' + - ');' + - 'CREATE INDEX IF NOT EXISTS wallet_balance ON wallet(balance);' + - 'COMMIT;') - } - - getWallet(conditions:string) { - return this.sqlFindOne({ conditions }) - } - - saveWallet(wallet:DBWallet) { - return this.saveEntity(wallet) - } -} diff --git a/app/lib/db/DBTx.ts b/app/lib/db/DBTx.ts new file mode 100644 index 000000000..1d47b7bb0 --- /dev/null +++ b/app/lib/db/DBTx.ts @@ -0,0 +1,60 @@ +import {TransactionDTO} from "../dto/TransactionDTO" + +export class DBTx { + hash: string + block_number: number | null + locktime: number + version: number + currency: string + comment: string + blockstamp: string + blockstampTime: number | null + time: number | null + inputs: string[] + unlocks: string[] + outputs: string[] + issuers: string[] + signatures: string[] + recipients: string[] + written: boolean + removed: boolean + received: number + output_base: number + output_amount: number + written_on: string + writtenOn: number + + static fromTransactionDTO(tx:TransactionDTO) { + const dbTx = new DBTx() + dbTx.hash = tx.hash + dbTx.locktime = tx.locktime + dbTx.version = tx.version + dbTx.currency = tx.currency + dbTx.blockstamp = tx.blockstamp + dbTx.blockstampTime = tx.blockstampTime + dbTx.comment = tx.comment || "" + dbTx.inputs = tx.inputs + dbTx.unlocks = tx.unlocks + dbTx.outputs = tx.outputs + dbTx.issuers = tx.issuers + dbTx.signatures = tx.signatures + dbTx.recipients = tx.outputsAsRecipients() + dbTx.written = false + dbTx.removed = false + dbTx.output_base = tx.output_base + dbTx.output_amount = tx.output_amount + return dbTx + } + + static setRecipients(txs:DBTx[]) { + // Each transaction must have a good "recipients" field for future searchs + txs.forEach((tx) => tx.recipients = DBTx.outputs2recipients(tx)) + } + + static outputs2recipients(tx:DBTx) { + return tx.outputs.map(function(out) { + const recipent = out.match('SIG\\((.*)\\)') + return (recipent && recipent[1]) || 'UNKNOWN' + }) + } +} diff --git a/app/lib/db/DBWallet.ts b/app/lib/db/DBWallet.ts new file mode 100644 index 000000000..d59c617d6 --- /dev/null +++ b/app/lib/db/DBWallet.ts @@ -0,0 +1,4 @@ +export interface DBWallet { + conditions: string + balance: number +} diff --git a/app/lib/indexer.ts b/app/lib/indexer.ts index 11c1f1ffa..cff677eb0 100644 --- a/app/lib/indexer.ts +++ b/app/lib/indexer.ts @@ -24,9 +24,9 @@ import {CommonConstants} from "./common-libs/constants" import {MembershipDTO} from "./dto/MembershipDTO" import {UnlockMetadata} from "./common-libs/txunlock" import {FileDAL} from "./dal/fileDAL" -import {DBWallet} from "./dal/sqliteDAL/WalletDAL" import {DataErrors} from "./common-libs/errors" import {DBBlock} from "./db/DBBlock" +import {DBWallet} from "./db/DBWallet" const _ = require('underscore'); diff --git a/app/lib/rules/global_rules.ts b/app/lib/rules/global_rules.ts index ca5042161..56c1c8843 100644 --- a/app/lib/rules/global_rules.ts +++ b/app/lib/rules/global_rules.ts @@ -22,7 +22,7 @@ import {CommonConstants} from "../common-libs/constants" import {IdentityDTO} from "../dto/IdentityDTO" import {hashf} from "../common" import {Indexer} from "../indexer" -import {DBTx} from "../dal/sqliteDAL/TxsDAL" +import {DBTx} from "../db/DBTx" const _ = require('underscore') diff --git a/app/modules/bma/lib/controllers/transactions.ts b/app/modules/bma/lib/controllers/transactions.ts index f9e3f36a3..7676feaa8 100644 --- a/app/modules/bma/lib/controllers/transactions.ts +++ b/app/modules/bma/lib/controllers/transactions.ts @@ -17,7 +17,7 @@ import {Source} from "../entity/source"; import {BMAConstants} from "../constants"; import {TransactionDTO} from "../../../../lib/dto/TransactionDTO"; import {HttpSources, HttpTransaction, HttpTxHistory, HttpTxOfHistory, HttpTxPending} from "../dtos"; -import {DBTx} from "../../../../lib/dal/sqliteDAL/TxsDAL"; +import {DBTx} from "../../../../lib/db/DBTx" const _ = require('underscore'); const http2raw = require('../http2raw'); diff --git a/app/service/TransactionsService.ts b/app/service/TransactionsService.ts index ec84b5739..489ed660e 100644 --- a/app/service/TransactionsService.ts +++ b/app/service/TransactionsService.ts @@ -11,16 +11,15 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; import {ConfDTO} from "../lib/dto/ConfDTO"; import {FileDAL} from "../lib/dal/fileDAL"; import {TransactionDTO} from "../lib/dto/TransactionDTO"; import {LOCAL_RULES_HELPERS} from "../lib/rules/local_rules"; import {GLOBAL_RULES_HELPERS} from "../lib/rules/global_rules"; -import {DBTx} from "../lib/dal/sqliteDAL/TxsDAL"; import {FIFOService} from "./FIFOService"; import {GlobalFifoPromise} from "./GlobalFifoPromise"; import {DataErrors} from "../lib/common-libs/errors" +import {DBTx} from "../lib/db/DBTx" const constants = require('../lib/constants'); -- GitLab