diff --git a/api/http/states.js b/api/http/states.js index ed010c1d..2dd98228 100644 --- a/api/http/states.js +++ b/api/http/states.js @@ -27,6 +27,7 @@ function StatesHttpApi (statesModule, app) { router.map(statesModule.internal, { 'get /get': 'getTransactions', + 'post /get': 'getTransactions', 'post /normalize': 'normalize', 'post /store': 'store' }); diff --git a/logic/transaction.js b/logic/transaction.js index ff6acf44..aec2b532 100644 --- a/logic/transaction.js +++ b/logic/transaction.js @@ -897,9 +897,21 @@ Transaction.prototype.applyUnconfirmed = function (trs, sender, requester, cb) { amount = amount.toNumber(); if (this.scope.clientWs) { - this.scope.clientWs.emit(trs); + var new_trs = Object.assign({}, trs); + new_trs.block_timestamp = null; + if (!new_trs.recipientPublicKey && new_trs.recipientId) { + this.scope.db.query(`SELECT ENCODE ("publicKey", \'hex\') AS "publicKey" from mem_accounts WHERE address='` + new_trs.recipientId + `' limit 1`).then((rows) => { + if (rows[0]) { + new_trs.recipientPublicKey = rows[0]['publicKey']; + } + this.scope.clientWs.emit(new_trs); + }).catch((err) => { + this.scope.logger.error(err.stack); + }); + } else { + this.scope.clientWs.emit(new_trs); + } } - this.scope.account.merge(sender.address, { u_balance: -amount }, function (err, sender) { @@ -1195,6 +1207,7 @@ Transaction.prototype.dbRead = function (raw) { height: raw.b_height, blockId: raw.b_id || raw.t_blockId, type: parseInt(raw.t_type), + block_timestamp: parseInt(raw.block_timestamp), timestamp: parseInt(raw.t_timestamp), senderPublicKey: raw.t_senderPublicKey, requesterPublicKey: raw.t_requesterPublicKey, @@ -1209,7 +1222,9 @@ Transaction.prototype.dbRead = function (raw) { confirmations: parseInt(raw.confirmations), asset: {} }; - + if (!tx.block_timestamp && raw.b_timestamp) { + tx.block_timestamp = parseInt(raw.b_timestamp); + } if (!__private.types[tx.type]) { throw 'Unknown transaction type ' + tx.type; } diff --git a/modules/states.js b/modules/states.js index 82c74842..facbfd97 100644 --- a/modules/states.js +++ b/modules/states.js @@ -126,7 +126,14 @@ __private.list = function (filter, cb) { params.key = filter.key; } where.push('"t_type" = '+ transactionTypes.STATE); - + if (filter.senderIds) { + where.push('"t_senderId" IN (${senderIds:csv})'); + params.senderIds = filter.senderIds; + } + if (filter.keyIds) { + where.push('"st_stored_key" IN (${keyIds:csv})'); + params.keyIds = filter.keyIds; + } if (filter.senderId) { where.push('"t_senderId" = ${name}'); params.name = filter.senderId; @@ -227,7 +234,7 @@ States.prototype.internal = { _.each(req.body, function (value, key) { var param = String(key).replace(pattern, ''); // Dealing with array-like parameters (csv comma separated) - if (_.includes(['senderIds', 'senderPublicKeys'], param)) { + if (_.includes(['senderIds', 'senderPublicKeys', 'keyIds'], param)) { value = String(value).split(','); req.body[key] = value; } diff --git a/package.json b/package.json index f54a1a19..aae95d3a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "adamant", - "version": "0.5.2", + "version": "0.6.0", "private": true, "scripts": { "start": "node app.js", @@ -37,9 +37,9 @@ "json-schema": "=0.2.3", "json-sql": "LiskHQ/json-sql#27e1ed1", "lisk-sandbox": "LiskHQ/lisk-sandbox#162da38", - "lodash": "=4.17.11", + "lodash": "=4.17.15", "method-override": "=2.3.10", - "npm": "=2.15.10", + "npm": "=6.13.4", "pg-monitor": "=0.7.1", "pg-native": "=1.10.0", "pg-promise": "=5.5.6", diff --git a/schema/states.js b/schema/states.js index 87ebc198..5a34680d 100644 --- a/schema/states.js +++ b/schema/states.js @@ -46,6 +46,16 @@ module.exports = { format: 'publicKey' } }, + keysIds: { + type: 'array', + minItems: 1, + 'items': { + type: 'string', + format: 'address', + minLength: 1, + maxLength: 22 + } + }, senderIds: { type: 'array', minItems: 1, diff --git a/sql/chats.js b/sql/chats.js index 1222b21b..abfaa4cb 100644 --- a/sql/chats.js +++ b/sql/chats.js @@ -99,6 +99,7 @@ var ChatsSql = { 'first("t_recipientId" ORDER BY b_height DESC, t_timestamp DESC) as "t_recipientId",', 'first("t_timestamp" ORDER BY b_height DESC, t_timestamp DESC) as "t_timestamp",', 'first("t_timestamp" ORDER BY b_height DESC, t_timestamp DESC) as "timestamp",', + 'first("b_timestamp" ORDER BY b_height DESC, b_timestamp DESC) as "block_timestamp",', 'first("t_amount" ORDER BY b_height DESC, t_timestamp DESC) as "t_amount",', 'first("t_fee" ORDER BY b_height DESC, t_timestamp DESC) as "t_fee",', 'first("c_message" ORDER BY b_height DESC, t_timestamp DESC) as "c_message",', diff --git a/sql/migrations/20190815120200_recreateTrsListFullView.sql b/sql/migrations/20190815120200_recreateTrsListFullView.sql new file mode 100644 index 00000000..d5133112 --- /dev/null +++ b/sql/migrations/20190815120200_recreateTrsListFullView.sql @@ -0,0 +1,50 @@ +/* + * create 'trs_list_full' view, normalize addresses, add indexes + */ + +BEGIN; + +DROP VIEW IF EXISTS trs_list_full; + +CREATE VIEW trs_list_full AS + +SELECT t."id" AS "t_id", + b."height" AS "b_height", + t."blockId" AS "t_blockId", + t."type" AS "t_type", + t."timestamp" AS "t_timestamp", + b."timestamp" AS "b_timestamp", + t."senderPublicKey" AS "t_senderPublicKey", + m."publicKey" AS "m_recipientPublicKey", + UPPER(t."senderId") AS "t_senderId", + UPPER(t."recipientId") AS "t_recipientId", + t."amount" AS "t_amount", + t."fee" AS "t_fee", + ENCODE(t."signature", 'hex') AS "t_signature", + ENCODE(t."signSignature", 'hex') AS "t_SignSignature", + t."signatures" AS "t_signatures", + (SELECT height + 1 FROM blocks ORDER BY height DESC LIMIT 1) - b."height" AS "confirmations", + d."username" AS "d_username", + v."votes" AS "v_votes", + ms."min" AS "m_min", + ms."lifetime" AS "m_lifetime", + ms."keysgroup" AS "m_keysgroup", + c."message" AS "c_message", + c."own_message" AS "c_own_message", + c."type" AS "c_type", + st."type" as "st_type", + st."stored_value" as "st_stored_value", + st."stored_key" as "st_stored_key" +FROM trs t + +LEFT JOIN blocks b ON t."blockId" = b."id" +LEFT JOIN mem_accounts m ON t."recipientId" = m."address" +LEFT OUTER JOIN delegates AS d ON d."transactionId" = t."id" +LEFT OUTER JOIN votes AS v ON v."transactionId" = t."id" +LEFT OUTER JOIN signatures AS s ON s."transactionId" = t."id" +LEFT OUTER JOIN multisignatures AS ms ON ms."transactionId" = t."id" +LEFT OUTER JOIN chats AS c ON c."transactionId" = t."id" +LEFT OUTER JOIN states AS st ON st."transactionId" = t."id"; + + +COMMIT; diff --git a/sql/migrations/20190815120437_recreateTrsListView.sql b/sql/migrations/20190815120437_recreateTrsListView.sql new file mode 100644 index 00000000..c095c325 --- /dev/null +++ b/sql/migrations/20190815120437_recreateTrsListView.sql @@ -0,0 +1,36 @@ +/* + * Recreate 'trs_list' view, normalize addresses, add indexes + */ + +BEGIN; + +DROP VIEW IF EXISTS trs_list; + +CREATE VIEW trs_list AS + +SELECT t."id" AS "t_id", + b."height" AS "b_height", + t."blockId" AS "t_blockId", + t."type" AS "t_type", + t."timestamp" AS "t_timestamp", + b."timestamp" AS "b_timestamp", + t."senderPublicKey" AS "t_senderPublicKey", + m."publicKey" AS "m_recipientPublicKey", + UPPER(t."senderId") AS "t_senderId", + UPPER(t."recipientId") AS "t_recipientId", + t."amount" AS "t_amount", + t."fee" AS "t_fee", + ENCODE(t."signature", 'hex') AS "t_signature", + ENCODE(t."signSignature", 'hex') AS "t_SignSignature", + t."signatures" AS "t_signatures", + (SELECT height + 1 FROM blocks ORDER BY height DESC LIMIT 1) - b."height" AS "confirmations" + +FROM trs t + +LEFT JOIN blocks b ON t."blockId" = b."id" +LEFT JOIN mem_accounts m ON t."recipientId" = m."address"; + +CREATE INDEX IF NOT EXISTS "trs_upper_sender_id" ON "trs"(UPPER("senderId")); +CREATE INDEX IF NOT EXISTS "trs_upper_recipient_id" ON "trs"(UPPER("recipientId")); + +COMMIT; diff --git a/sql/states.js b/sql/states.js index 9d4787e9..ae2fbb46 100644 --- a/sql/states.js +++ b/sql/states.js @@ -31,7 +31,7 @@ var StatesSql = { list: function (params) { return [ - 'SELECT *, t_timestamp as timestamp FROM full_blocks_list', + 'SELECT *, t_timestamp as timestamp, b_timestamp as block_timestamp FROM full_blocks_list', (params.where.length ? 'WHERE ' + params.where.join(' AND ') : ''), (params.sortField ? 'ORDER BY ' + [params.sortField, params.sortMethod].join(' ') : ''), 'LIMIT ${limit} OFFSET ${offset}' diff --git a/sql/transactions.js b/sql/transactions.js index edad2934..de60b273 100644 --- a/sql/transactions.js +++ b/sql/transactions.js @@ -31,7 +31,7 @@ var TransactionsSql = { list: function (params) { return [ - 'SELECT "t_id", "b_height", "t_blockId", "t_type", "t_timestamp", "t_senderId", "t_recipientId",', + 'SELECT "t_id", "b_height", "t_blockId", "t_type", "t_timestamp", "b_timestamp" as "block_timestamp", "t_senderId", "t_recipientId",', '"t_amount", "t_fee", "t_signature", "t_SignSignature", "t_signatures", "confirmations",', 'ENCODE ("t_senderPublicKey", \'hex\') AS "t_senderPublicKey", ENCODE ("m_recipientPublicKey", \'hex\') AS "m_recipientPublicKey"', 'FROM trs_list', @@ -45,7 +45,7 @@ var TransactionsSql = { }, listFull: function (params) { return [ - 'SELECT "t_id", "b_height", "t_blockId", "t_type", "t_timestamp", "t_senderId", "t_recipientId",', + 'SELECT "t_id", "b_height", "t_blockId", "t_type", "t_timestamp", "b_timestamp" as "block_timestamp", "t_senderId", "t_recipientId",', '"t_amount", "t_fee", "t_signature", "t_SignSignature", "t_signatures", "confirmations",', 'ENCODE ("t_senderPublicKey", \'hex\') AS "t_senderPublicKey", ENCODE ("m_recipientPublicKey", \'hex\') AS "m_recipientPublicKey",', '"d_username", "v_votes", "m_min", "m_lifetime", "m_keysgroup", "c_message", "c_own_message", "c_type", "st_type", "st_stored_value", "st_stored_key" ',