Commit c7c8d9fe authored by Cédric Moreau's avatar Cédric Moreau
Browse files

[enh] Remove SQL obsolete code

parent 9641c5e5
......@@ -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')
......
......@@ -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')
......
......@@ -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
};
......
......@@ -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,
......
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> {
......
import {Initiable} from "../../sqliteDAL/Initiable"
import {DBWallet} from "../../sqliteDAL/WalletDAL"
import {DBWallet} from "../../../db/DBWallet"
export interface WalletDAO extends Initiable {
......
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')
......
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 {
......
// 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]);
}
}
......@@ -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) {
......
// 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