From afb3cfe223fc986e807fc11380383a36c94b7a69 Mon Sep 17 00:00:00 2001
From: Benoit Lavenier <benoit.lavenier@e-is.pro>
Date: Wed, 31 May 2023 13:35:18 +0200
Subject: [PATCH] [fix] Report changes from merge request !1425 to release/1.8
 - close #1442

---
 app/lib/dal/fileDAL.ts                        | 39 +++-----
 app/lib/dal/indexDAL/abstract/TxsDAO.ts       | 25 +++++
 .../dal/indexDAL/sqlite/SqliteTransactions.ts | 98 +++++++++++++++++++
 app/modules/bma/lib/bma.ts                    |  2 +-
 .../bma/lib/controllers/transactions.ts       | 85 +++++++---------
 app/modules/bma/lib/dtos.ts                   |  5 +-
 6 files changed, 175 insertions(+), 79 deletions(-)

diff --git a/app/lib/dal/fileDAL.ts b/app/lib/dal/fileDAL.ts
index 585e0d2a6..b20aaf2b5 100644
--- a/app/lib/dal/fileDAL.ts
+++ b/app/lib/dal/fileDAL.ts
@@ -1406,31 +1406,20 @@ export class FileDAL implements ServerDAO {
     return this.txsDAL.addPending(tx);
   }
 
-  async getTransactionsHistory(pubkey: string) {
-    const history: {
-      sent: DBTx[];
-      received: DBTx[];
-      sending: DBTx[];
-      receiving: DBTx[];
-      pending: DBTx[];
-    } = {
-      sent: [],
-      received: [],
-      sending: [],
-      receiving: [],
-      pending: [],
-    };
-    const res = await Promise.all([
-      this.txsDAL.getLinkedWithIssuer(pubkey),
-      this.txsDAL.getLinkedWithRecipient(pubkey),
-      this.txsDAL.getPendingWithIssuer(pubkey),
-      this.txsDAL.getPendingWithRecipient(pubkey),
-    ]);
-    history.sent = res[0] || [];
-    history.received = res[1] || [];
-    history.sending = res[2] || [];
-    history.pending = res[3] || [];
-    return history;
+  async getTxHistoryByPubkey(pubkey: string) {
+    return this.txsDAL.getTxHistoryByPubkey(pubkey);
+  }
+
+  getTxHistoryByPubkeyBetweenBlocks(pubkey: string, from: number, to: number) {
+    return this.txsDAL.getTxHistoryByPubkeyBetweenBlocks(pubkey, +from, +to);
+  }
+
+  getTxHistoryByPubkeyBetweenTimes(pubkey: string, from: number, to: number) {
+    return this.txsDAL.getTxHistoryByPubkeyBetweenTimes(pubkey, +from, +to);
+  }
+
+  getTxHistoryMempool(pubkey: string) {
+    return this.txsDAL.getTxHistoryMempool(pubkey);
   }
 
   async getUDHistory(pubkey: string): Promise<{ history: HttpUD[] }> {
diff --git a/app/lib/dal/indexDAL/abstract/TxsDAO.ts b/app/lib/dal/indexDAL/abstract/TxsDAO.ts
index 3003b4458..7ef9e06de 100644
--- a/app/lib/dal/indexDAL/abstract/TxsDAO.ts
+++ b/app/lib/dal/indexDAL/abstract/TxsDAO.ts
@@ -18,6 +18,31 @@ export interface TxsDAO extends GenericDAO<DBTx> {
 
   addPending(dbTx: DBTx): Promise<DBTx>;
 
+  getTxHistoryByPubkey(
+    pubkey: string
+  ): Promise<{
+    sent: DBTx[];
+    received: DBTx[];
+    sending: DBTx[];
+    pending: DBTx[];
+  }>;
+
+  getTxHistoryByPubkeyBetweenBlocks(
+    pubkey: string,
+    from: number,
+    to: number
+  ): Promise<{ sent: DBTx[]; received: DBTx[] }>;
+
+  getTxHistoryByPubkeyBetweenTimes(
+    pubkey: string,
+    from: number,
+    to: number
+  ): Promise<{ sent: DBTx[]; received: DBTx[] }>;
+
+  getTxHistoryMempool(
+    pubkey: string
+  ): Promise<{ sending: DBTx[]; pending: DBTx[] }>;
+
   getLinkedWithIssuer(pubkey: string): Promise<DBTx[]>;
 
   getLinkedWithRecipient(pubkey: string): Promise<DBTx[]>;
diff --git a/app/lib/dal/indexDAL/sqlite/SqliteTransactions.ts b/app/lib/dal/indexDAL/sqlite/SqliteTransactions.ts
index f2a6e104a..429f9aba0 100644
--- a/app/lib/dal/indexDAL/sqlite/SqliteTransactions.ts
+++ b/app/lib/dal/indexDAL/sqlite/SqliteTransactions.ts
@@ -147,6 +147,104 @@ export class SqliteTransactions extends SqliteTable<DBTx> implements TxsDAO {
     return this.findEntities("SELECT * FROM txs WHERE NOT written", []);
   }
 
+  async getTxHistoryByPubkey(pubkey: string) {
+    const history: {
+      sent: DBTx[];
+      received: DBTx[];
+      sending: DBTx[];
+      pending: DBTx[];
+    } = {
+      sent: [],
+      received: [],
+      sending: [],
+      pending: [],
+    };
+    const res = await Promise.all([
+      this.getLinkedWithIssuer(pubkey),
+      this.getLinkedWithRecipient(pubkey),
+      this.getPendingWithIssuer(pubkey),
+      this.getPendingWithRecipient(pubkey),
+    ]);
+    history.sent = res[0] || [];
+    history.received = res[1] || [];
+    history.sending = res[2] || [];
+    history.pending = res[3] || [];
+    return history;
+  }
+
+  async getTxHistoryByPubkeyBetweenBlocks(
+    pubkey: string,
+    from: number,
+    to: number
+  ): Promise<{ sent: DBTx[]; received: DBTx[] }> {
+    const history: {
+      sent: DBTx[];
+      received: DBTx[];
+    } = {
+      sent: [],
+      received: [],
+    };
+    const res = await Promise.all([
+      this.findEntities(
+        "SELECT * FROM txs WHERE written AND issuers LIKE ? AND block_number >= ? AND block_number <= ?",
+        [`%${pubkey}%`, from, to]
+      ),
+      this.findEntities(
+        "SELECT * FROM txs WHERE written AND recipients LIKE ? AND block_number >= ? AND block_number <= ?",
+        [`%${pubkey}%`, from, to]
+      ),
+    ]);
+    history.sent = res[0] || [];
+    history.received = res[1] || [];
+    return history;
+  }
+
+  async getTxHistoryByPubkeyBetweenTimes(
+    pubkey: string,
+    from: number,
+    to: number
+  ): Promise<{ sent: DBTx[]; received: DBTx[] }> {
+    const history: {
+      sent: DBTx[];
+      received: DBTx[];
+    } = {
+      sent: [],
+      received: [],
+    };
+    const res = await Promise.all([
+      this.findEntities(
+        "SELECT * FROM txs WHERE written AND issuers LIKE ? AND time >= ? AND time <= ?",
+        [`%${pubkey}%`, from, to]
+      ),
+      this.findEntities(
+        "SELECT * FROM txs WHERE written AND recipients LIKE ? AND time >= ? AND time <= ?",
+        [`%${pubkey}%`, from, to]
+      ),
+    ]);
+    history.sent = res[0] || [];
+    history.received = res[1] || [];
+    return history;
+  }
+
+  async getTxHistoryMempool(
+    pubkey: string
+  ): Promise<{ sending: DBTx[]; pending: DBTx[] }> {
+    const history: {
+      sending: DBTx[];
+      pending: DBTx[];
+    } = {
+      sending: [],
+      pending: [],
+    };
+    const res = await Promise.all([
+      this.getPendingWithIssuer(pubkey),
+      this.getPendingWithRecipient(pubkey),
+    ]);
+    history.sending = res[0] || [];
+    history.pending = res[1] || [];
+    return history;
+  }
+
   getLinkedWithIssuer(pubkey: string): Promise<DBTx[]> {
     return this.findEntities(
       "SELECT * FROM txs WHERE written AND issuers LIKE ?",
diff --git a/app/modules/bma/lib/bma.ts b/app/modules/bma/lib/bma.ts
index 013509fd1..147b74d6b 100644
--- a/app/modules/bma/lib/bma.ts
+++ b/app/modules/bma/lib/bma.ts
@@ -305,7 +305,7 @@ export const bma = function (
       );
       httpMethods.httpGET(
         "/tx/history/:pubkey/pending",
-        (req: any) => transactions.getPendingForPubkey(req),
+        (req: any) => transactions.getPendingByPubkey(req),
         BMALimitation.limitAsHighUsage()
       );
       httpMethods.httpGET(
diff --git a/app/modules/bma/lib/controllers/transactions.ts b/app/modules/bma/lib/controllers/transactions.ts
index 84ea38d13..37ab7b2af 100644
--- a/app/modules/bma/lib/controllers/transactions.ts
+++ b/app/modules/bma/lib/controllers/transactions.ts
@@ -18,17 +18,17 @@ import { TransactionDTO } from "../../../../lib/dto/TransactionDTO";
 import {
   HttpSources,
   HttpTransaction,
+  HttpTransactionPending,
   HttpTxHistory,
   HttpTxOfHistory,
   HttpTxPending,
 } from "../dtos";
 import { DBTx } from "../../../../lib/db/DBTx";
-import { Underscore } from "../../../../lib/common-libs/underscore";
 
 const http2raw = require("../http2raw");
 
 export class TransactionBinding extends AbstractController {
-  async parseTransaction(req: any): Promise<HttpTransaction> {
+  async parseTransaction(req: any): Promise<HttpTransactionPending> {
     const res = await this.pushEntity(
       req,
       http2raw.transaction,
@@ -45,8 +45,6 @@ export class TransactionBinding extends AbstractController {
       comment: res.comment,
       locktime: res.locktime,
       hash: res.hash,
-      written_block: res.blockNumber,
-      raw: res.getRaw(),
     };
   }
 
@@ -72,8 +70,6 @@ export class TransactionBinding extends AbstractController {
       version: tx.version,
       currency: tx.currency,
       locktime: tx.locktime,
-      // blockstamp: tx.blockstamp,
-      // blockstampTime: tx.blockstampTime,
       issuers: tx.issuers,
       inputs: tx.inputs,
       outputs: tx.outputs,
@@ -81,60 +77,47 @@ export class TransactionBinding extends AbstractController {
       signatures: tx.signatures,
       comment: tx.comment,
       hash: tx.hash,
-      // time: tx.time,
-      // block_number: tx.block_number,
       written_block: tx.block_number,
-      // received: tx.received,
+      writtenTime: tx.time,
       raw: "",
     };
   }
 
   async getHistory(req: any): Promise<HttpTxHistory> {
     const pubkey = await ParametersService.getPubkeyP(req);
-    return this.getFilteredHistory(pubkey, (results: any) => results);
+    const history = await this.server.dal.getTxHistoryByPubkey(pubkey);
+    return this.toHttpTxHistory(pubkey, history);
   }
 
   async getHistoryBetweenBlocks(req: any): Promise<HttpTxHistory> {
     const pubkey = await ParametersService.getPubkeyP(req);
     const from = await ParametersService.getFromP(req);
     const to = await ParametersService.getToP(req);
-    return this.getFilteredHistory(pubkey, (res: any) => {
-      const histo = res.history;
-      histo.sent = Underscore.filter(histo.sent, function (tx: any) {
-        return tx && tx.block_number >= from && tx.block_number <= to;
-      });
-      histo.received = Underscore.filter(histo.received, function (tx: any) {
-        return tx && tx.block_number >= from && tx.block_number <= to;
-      });
-      Underscore.extend(histo, { sending: [], receiving: [] });
-      return res;
-    });
+
+    const history = await this.server.dal.getTxHistoryByPubkeyBetweenBlocks(
+      pubkey,
+      +from,
+      +to
+    );
+    return this.toHttpTxHistory(pubkey, history);
   }
 
   async getHistoryBetweenTimes(req: any): Promise<HttpTxHistory> {
     const pubkey = await ParametersService.getPubkeyP(req);
     const from = await ParametersService.getFromP(req);
     const to = await ParametersService.getToP(req);
-    return this.getFilteredHistory(pubkey, (res: any) => {
-      const histo = res.history;
-      histo.sent = Underscore.filter(histo.sent, function (tx: any) {
-        return tx && tx.time >= from && tx.time <= to;
-      });
-      histo.received = Underscore.filter(histo.received, function (tx: any) {
-        return tx && tx.time >= from && tx.time <= to;
-      });
-      Underscore.extend(histo, { sending: [], receiving: [] });
-      return res;
-    });
+    const history = await this.server.dal.getTxHistoryByPubkeyBetweenTimes(
+      pubkey,
+      +from,
+      +to
+    );
+    return this.toHttpTxHistory(pubkey, history);
   }
 
-  async getPendingForPubkey(req: any): Promise<HttpTxHistory> {
+  async getPendingByPubkey(req: any): Promise<HttpTxHistory> {
     const pubkey = await ParametersService.getPubkeyP(req);
-    return this.getFilteredHistory(pubkey, function (res: any) {
-      const histo = res.history;
-      Underscore.extend(histo, { sent: [], received: [] });
-      return res;
-    });
+    const history = await this.server.dal.getTxHistoryMempool(pubkey);
+    return this.toHttpTxHistory(pubkey, history);
   }
 
   async getPending(): Promise<HttpTxPending> {
@@ -145,6 +128,7 @@ export class TransactionBinding extends AbstractController {
         const tx = TransactionDTO.fromJSONObject(t);
         return {
           version: tx.version,
+          currency: tx.currency,
           issuers: tx.issuers,
           inputs: tx.inputs,
           unlocks: tx.unlocks,
@@ -160,23 +144,25 @@ export class TransactionBinding extends AbstractController {
     };
   }
 
-  private async getFilteredHistory(
+  private async toHttpTxHistory(
     pubkey: string,
-    filter: any
+    dbTxHistory: {
+      sent?: DBTx[];
+      received?: DBTx[];
+      sending?: DBTx[];
+      pending?: DBTx[];
+    }
   ): Promise<HttpTxHistory> {
-    let history = await this.server.dal.getTransactionsHistory(pubkey);
-    let result = {
+    return {
       currency: this.conf.currency,
       pubkey: pubkey,
       history: {
-        sending: history.sending.map(dbtx2HttpTxOfHistory),
-        received: history.received.map(dbtx2HttpTxOfHistory),
-        receiving: history.receiving.map(dbtx2HttpTxOfHistory),
-        sent: history.sent.map(dbtx2HttpTxOfHistory),
-        pending: history.pending.map(dbtx2HttpTxOfHistory),
+        sending: dbTxHistory.sending?.map(dbtx2HttpTxOfHistory) || [],
+        received: dbTxHistory.received?.map(dbtx2HttpTxOfHistory) || [],
+        sent: dbTxHistory.sent?.map(dbtx2HttpTxOfHistory) || [],
+        pending: dbTxHistory.pending?.map(dbtx2HttpTxOfHistory) || [],
       },
     };
-    return filter(result);
   }
 }
 
@@ -193,8 +179,7 @@ function dbtx2HttpTxOfHistory(tx: DBTx): HttpTxOfHistory {
     signatures: tx.signatures,
     comment: tx.comment,
     hash: tx.hash,
-    time: tx.time,
+    time: tx.time || tx.received,
     block_number: tx.block_number,
-    received: tx.received,
   };
 }
diff --git a/app/modules/bma/lib/dtos.ts b/app/modules/bma/lib/dtos.ts
index dcf1ebe25..ee187a77e 100644
--- a/app/modules/bma/lib/dtos.ts
+++ b/app/modules/bma/lib/dtos.ts
@@ -781,10 +781,12 @@ export interface HttpTransaction {
   signatures: string[];
   raw: string;
   written_block: number | null;
+  writtenTime: number | null;
   hash: string;
 }
 
 export interface HttpTransactionPending {
+  currency: string;
   version: number;
   issuers: string[];
   inputs: string[];
@@ -851,7 +853,6 @@ export interface HttpTxOfHistory {
   outputs: string[];
   comment: string;
   locktime: number;
-  received: number;
   signatures: string[];
   hash: string;
   block_number: number | null;
@@ -867,7 +868,6 @@ export const TxHistory = {
     sent: [TxOfHistory],
     received: [TxOfHistory],
     sending: [TxOfHistory],
-    receiving: [TxOfHistory],
     pending: [TxOfHistory],
   },
 };
@@ -879,7 +879,6 @@ export interface HttpTxHistory {
     sent: HttpTxOfHistory[];
     received: HttpTxOfHistory[];
     sending: HttpTxOfHistory[];
-    receiving: HttpTxOfHistory[];
     pending: HttpTxOfHistory[];
   };
 }
-- 
GitLab