|
|
@ -5,14 +5,12 @@ |
|
|
|
'use strict' |
|
|
|
|
|
|
|
const mysql = require('mysql') |
|
|
|
const path = require('path') |
|
|
|
const Logger = require('../logger') |
|
|
|
const util = require('../util') |
|
|
|
const errors = require('../errors') |
|
|
|
const hdaHelper = require('../bitcoin/hd-accounts-helper') |
|
|
|
const network = require('../bitcoin/network') |
|
|
|
const keys = require('../../keys/')[network.key] |
|
|
|
const keysDb = keys.db |
|
|
|
const debug = !!(process.argv.indexOf('db-debug') > -1) |
|
|
|
const queryDebug = !!(process.argv.indexOf('dbquery-debug') > -1) |
|
|
|
|
|
|
@ -389,8 +387,8 @@ class MySqlDbWrapper { |
|
|
|
this.pool.query(query, null, async (err, result, fields) => { |
|
|
|
if (err) { |
|
|
|
// Retry the request on lock errors
|
|
|
|
if ((err.code == 'ER_LOCK_DEADLOCK' || |
|
|
|
err.code == 'ER_LOCK_TIMEOUT' || |
|
|
|
if ((err.code == 'ER_LOCK_DEADLOCK' || |
|
|
|
err.code == 'ER_LOCK_TIMEOUT' || |
|
|
|
err.code == 'ER_LOCK_WAIT_TIMEOUT') && (retries > 0) |
|
|
|
) { |
|
|
|
try { |
|
|
@ -438,7 +436,7 @@ class MySqlDbWrapper { |
|
|
|
|
|
|
|
if (result.length > 0) |
|
|
|
return result[0].addrID |
|
|
|
|
|
|
|
|
|
|
|
throw errors.db.ERROR_NO_ADDRESS |
|
|
|
} |
|
|
|
|
|
|
@ -455,7 +453,7 @@ class MySqlDbWrapper { |
|
|
|
|
|
|
|
if (result.length > 0) |
|
|
|
return result[0].addrID |
|
|
|
|
|
|
|
|
|
|
|
const sqlQuery2 = 'INSERT INTO `addresses` SET ?' |
|
|
|
const params2 = { addrAddress: address } |
|
|
|
const query2 = mysql.format(sqlQuery2, params2) |
|
|
@ -521,7 +519,7 @@ class MySqlDbWrapper { |
|
|
|
async getAddressBalance(address) { |
|
|
|
if (address == null) |
|
|
|
return null |
|
|
|
|
|
|
|
|
|
|
|
const sqlQuery = 'SELECT SUM(`outputs`.`outAmount`) as balance \ |
|
|
|
FROM `addresses` \ |
|
|
|
INNER JOIN `outputs` ON `outputs`.`addrID` = `addresses`.`addrID` \ |
|
|
@ -613,7 +611,7 @@ class MySqlDbWrapper { |
|
|
|
if (result.length > 0) |
|
|
|
return result[0].hdID |
|
|
|
|
|
|
|
throw errors.db.ERROR_NO_HD_ACCOUNT |
|
|
|
throw errors.db.ERROR_NO_HD_ACCOUNT |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@ -639,14 +637,14 @@ class MySqlDbWrapper { |
|
|
|
|
|
|
|
const sqlQuery2 = 'INSERT INTO `hd` SET ?' |
|
|
|
const params2 = { |
|
|
|
hdXpub: xpub, |
|
|
|
hdXpub: xpub, |
|
|
|
hdCreated: util.unix(), |
|
|
|
hdType: type, |
|
|
|
} |
|
|
|
const query2 = mysql.format(sqlQuery2, params2) |
|
|
|
const result2 = await this._query(query2) |
|
|
|
return result2.insertId |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@ -737,7 +735,7 @@ class MySqlDbWrapper { |
|
|
|
async addAddressesToHDAccount(xpub, addressData) { |
|
|
|
if (addressData.length == 0) |
|
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
const addresses = addressData.map(d => d.address) |
|
|
|
const hdID = await this.getHDAccountId(xpub) |
|
|
|
|
|
|
@ -801,10 +799,10 @@ class MySqlDbWrapper { |
|
|
|
* { |
|
|
|
* hd: { |
|
|
|
* [xpub]: { |
|
|
|
* hdID: N, |
|
|
|
* hdType: M, |
|
|
|
* hdID: N, |
|
|
|
* hdType: M, |
|
|
|
* addresses:[...] |
|
|
|
* }, |
|
|
|
* }, |
|
|
|
* ... |
|
|
|
* } |
|
|
|
* loose:[...] |
|
|
@ -1050,7 +1048,7 @@ class MySqlDbWrapper { |
|
|
|
|
|
|
|
const sqlQuery = 'SELECT COUNT(DISTINCT `r`.`txnTxid`) AS nbTxs \ |
|
|
|
FROM (' + subQuery + ') AS `r`' |
|
|
|
|
|
|
|
|
|
|
|
let query = mysql.format(sqlQuery) |
|
|
|
const results = await this._query(query) |
|
|
|
|
|
|
@ -1122,7 +1120,7 @@ class MySqlDbWrapper { |
|
|
|
if (txsIds.length == 0) |
|
|
|
return [] |
|
|
|
|
|
|
|
// Prepares subqueries for
|
|
|
|
// Prepares subqueries for
|
|
|
|
// the query retrieving utxos of interest
|
|
|
|
let subQuery2 = '' |
|
|
|
let subQueries2 = [] |
|
|
@ -1323,7 +1321,7 @@ class MySqlDbWrapper { |
|
|
|
async ensureTransactionId(txid) { |
|
|
|
const sqlQuery = 'INSERT IGNORE INTO `transactions` SET ?' |
|
|
|
const params = { |
|
|
|
txnTxid: txid, |
|
|
|
txnTxid: txid, |
|
|
|
txnCreated: util.unix() |
|
|
|
} |
|
|
|
const query = mysql.format(sqlQuery, params) |
|
|
@ -1473,7 +1471,7 @@ class MySqlDbWrapper { |
|
|
|
tx.time = Math.min(tx.time, output.blockTime) |
|
|
|
|
|
|
|
tx.time = Math.min(tx.time, output.txnCreated) |
|
|
|
|
|
|
|
|
|
|
|
if (output.blockHeight != null) |
|
|
|
tx.block_height = output.blockHeight |
|
|
|
|
|
|
@ -1532,7 +1530,7 @@ class MySqlDbWrapper { |
|
|
|
// Remove block height if null
|
|
|
|
if (tx.block_height == null) |
|
|
|
delete tx.block_height |
|
|
|
|
|
|
|
|
|
|
|
return tx |
|
|
|
} |
|
|
|
|
|
|
@ -1665,7 +1663,7 @@ class MySqlDbWrapper { |
|
|
|
|
|
|
|
/** |
|
|
|
* Get a list of outputs identified by their txid and index. |
|
|
|
* The presence of spendingTxnID and spendingInID not null indicate that an |
|
|
|
* The presence of spendingTxnID and spendingInID not null indicate that an |
|
|
|
* input spending the transaction output index is already in the database and |
|
|
|
* may indicate a DOUBLE SPEND. |
|
|
|
* @param {object[]} spends - array of {txid,index} |
|
|
@ -1673,10 +1671,10 @@ class MySqlDbWrapper { |
|
|
|
* {addrAddress, outID, outAmount, txnTxid, outIndex, spendingTxnID/null, spendingInID/null} |
|
|
|
*/ |
|
|
|
async getOutputSpends(spends) { |
|
|
|
if (spends.length == 0) |
|
|
|
if (spends.length == 0) |
|
|
|
return [] |
|
|
|
|
|
|
|
const whereClauses = |
|
|
|
const whereClauses = |
|
|
|
spends.map(s => '(`txnTxid`=' + this.pool.escape(s.txid) + ' AND `outIndex`=' + this.pool.escape(s.index) + ')') |
|
|
|
|
|
|
|
const whereClause = whereClauses.join(' OR ') |
|
|
@ -1796,10 +1794,10 @@ class MySqlDbWrapper { |
|
|
|
const params2 = block.blockHash |
|
|
|
const query2 = mysql.format(sqlQuery2, params2) |
|
|
|
const result2 = await this._query(query2) |
|
|
|
|
|
|
|
|
|
|
|
if (result2.length > 0) |
|
|
|
return result2[0].blockID |
|
|
|
|
|
|
|
return result2[0].blockID |
|
|
|
|
|
|
|
throw 'Problem met while trying to insert a new block' |
|
|
|
} |
|
|
|
|
|
|
@ -2009,7 +2007,7 @@ class MySqlDbWrapper { |
|
|
|
INNER JOIN `transactions` ON `outputs`.`txnID` = `transactions`.`txnID` \ |
|
|
|
WHERE `hd`.`hdCreated` > `transactions`.`txnCreated` \ |
|
|
|
GROUP BY `hd`.`hdID` LIMIT 100' |
|
|
|
|
|
|
|
|
|
|
|
return this._query(sqlQuery) |
|
|
|
} |
|
|
|
|
|
|
@ -2022,7 +2020,7 @@ class MySqlDbWrapper { |
|
|
|
INNER JOIN `blocks` ON `transactions`.`blockID` = `blocks`.`blockID` \ |
|
|
|
WHERE `transactions`.`txnCreated` > `blocks`.`blockTime` \ |
|
|
|
LIMIT 100' |
|
|
|
|
|
|
|
|
|
|
|
return this._query(sqlQuery) |
|
|
|
} |
|
|
|
|
|
|
|