|
|
@ -11,8 +11,8 @@ const errors = require('../errors') |
|
|
|
const hdaHelper = require('../bitcoin/hd-accounts-helper') |
|
|
|
const network = require('../bitcoin/network') |
|
|
|
const keys = require('../../keys/')[network.key] |
|
|
|
const debug = !!(process.argv.indexOf('db-debug') > -1) |
|
|
|
const queryDebug = !!(process.argv.indexOf('dbquery-debug') > -1) |
|
|
|
const debug = process.argv.indexOf('db-debug') > -1 |
|
|
|
const queryDebug = process.argv.indexOf('dbquery-debug') > -1 |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
@ -387,9 +387,9 @@ 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' || |
|
|
|
err.code == 'ER_LOCK_WAIT_TIMEOUT') && (retries > 0) |
|
|
|
if ((err.code === 'ER_LOCK_DEADLOCK' || |
|
|
|
err.code === 'ER_LOCK_TIMEOUT' || |
|
|
|
err.code === 'ER_LOCK_WAIT_TIMEOUT') && (retries > 0) |
|
|
|
) { |
|
|
|
try { |
|
|
|
this.queryError('Lock detected. Retry request in a few ms', query) |
|
|
@ -426,7 +426,7 @@ class MySqlDbWrapper { |
|
|
|
/** |
|
|
|
* Get the ID of an address |
|
|
|
* @param {string} address - bitcoin address |
|
|
|
* @returns {integer} returns the address id |
|
|
|
* @returns {number} returns the address id |
|
|
|
*/ |
|
|
|
async getAddressId(address) { |
|
|
|
const sqlQuery = 'SELECT `addrID` FROM `addresses` WHERE `addrAddress` = ?' |
|
|
@ -443,7 +443,7 @@ class MySqlDbWrapper { |
|
|
|
/** |
|
|
|
* Get the ID of an Address. Ensures that the address exists. |
|
|
|
* @param {string} address - bitcoin address |
|
|
|
* @returns {integer} returns the address id |
|
|
|
* @returns {number} returns the address id |
|
|
|
*/ |
|
|
|
async ensureAddressId(address) { |
|
|
|
const sqlQuery = 'SELECT `addrID` FROM `addresses` WHERE `addrAddress` = ?' |
|
|
@ -469,7 +469,7 @@ class MySqlDbWrapper { |
|
|
|
async getAddressesIds(addresses) { |
|
|
|
const ret = {} |
|
|
|
|
|
|
|
if (addresses.length == 0) |
|
|
|
if (addresses.length === 0) |
|
|
|
return ret |
|
|
|
|
|
|
|
const sqlQuery = 'SELECT * FROM `addresses` WHERE `addrAddress` IN (?)' |
|
|
@ -488,7 +488,7 @@ class MySqlDbWrapper { |
|
|
|
* @param {string[]} addresses - array of bitcoin addresses |
|
|
|
*/ |
|
|
|
async addAddresses(addresses) { |
|
|
|
if (addresses.length == 0) |
|
|
|
if (addresses.length === 0) |
|
|
|
return [] |
|
|
|
|
|
|
|
const sqlQuery = 'INSERT IGNORE INTO `addresses` (addrAddress) VALUES ?' |
|
|
@ -502,7 +502,7 @@ class MySqlDbWrapper { |
|
|
|
* @param {string[]} addresses - array of bitcoin addresses |
|
|
|
*/ |
|
|
|
async getAddresses(addresses) { |
|
|
|
if (addresses.length == 0) |
|
|
|
if (addresses.length === 0) |
|
|
|
return [] |
|
|
|
|
|
|
|
const sqlQuery = 'SELECT * FROM `addresses` WHERE `addrAddress` IN (?)' |
|
|
@ -514,7 +514,7 @@ class MySqlDbWrapper { |
|
|
|
/** |
|
|
|
* Get address balance. |
|
|
|
* @param {string} address - bitcoin address |
|
|
|
* @returns {integer} returns the balance of the address |
|
|
|
* @returns {number} returns the balance of the address |
|
|
|
*/ |
|
|
|
async getAddressBalance(address) { |
|
|
|
if (address == null) |
|
|
@ -532,7 +532,7 @@ class MySqlDbWrapper { |
|
|
|
const query = mysql.format(sqlQuery, params) |
|
|
|
const results = await this._query(query) |
|
|
|
|
|
|
|
if (results.length == 1) { |
|
|
|
if (results.length === 1) { |
|
|
|
const balance = results[0].balance |
|
|
|
return (balance == null) ? 0 : balance |
|
|
|
} |
|
|
@ -543,7 +543,7 @@ class MySqlDbWrapper { |
|
|
|
/** |
|
|
|
* Get the number of transactions for an address. |
|
|
|
* @param {string} address - bitcoin address |
|
|
|
* @returns {integer} returns the number of transactions for the address |
|
|
|
* @returns {number} returns the number of transactions for the address |
|
|
|
*/ |
|
|
|
async getAddressNbTransactions(address) { |
|
|
|
if(address == null) |
|
|
@ -571,7 +571,7 @@ class MySqlDbWrapper { |
|
|
|
const query = mysql.format(sqlQuery, params) |
|
|
|
const results = await this._query(query) |
|
|
|
|
|
|
|
if (results.length == 1) { |
|
|
|
if (results.length === 1) { |
|
|
|
const nbTxs = results[0].nbTxs |
|
|
|
return (nbTxs == null) ? 0 : nbTxs |
|
|
|
} |
|
|
@ -582,7 +582,7 @@ class MySqlDbWrapper { |
|
|
|
/** |
|
|
|
* Get an HD account. |
|
|
|
* @param {string} xpub - xpub |
|
|
|
* @returns {integer} returns {hdID, hdXpub, hdCreated, hdType} |
|
|
|
* @returns {number} returns {hdID, hdXpub, hdCreated, hdType} |
|
|
|
* throws if no record of xpub |
|
|
|
*/ |
|
|
|
async getHDAccount(xpub) { |
|
|
@ -600,7 +600,7 @@ class MySqlDbWrapper { |
|
|
|
/** |
|
|
|
* Get the ID of an HD account |
|
|
|
* @param {string} xpub - xpub |
|
|
|
* @returns {integer} returns the id of the hd account |
|
|
|
* @returns {number} returns the id of the hd account |
|
|
|
*/ |
|
|
|
async getHDAccountId(xpub) { |
|
|
|
const sqlQuery = 'SELECT `hdID` FROM `hd` WHERE `hdXpub` = ?' |
|
|
@ -618,7 +618,7 @@ class MySqlDbWrapper { |
|
|
|
* Get the ID of an HD account. Ensures that the account exists. |
|
|
|
* @param {string} xpub - xpub |
|
|
|
* @param {string} type - hd account type |
|
|
|
* @returns {integer} returns the id of the hd account |
|
|
|
* @returns {number} returns the id of the hd account |
|
|
|
*/ |
|
|
|
async ensureHDAccountId(xpub, type) { |
|
|
|
const info = hdaHelper.classify(type) |
|
|
@ -650,15 +650,14 @@ class MySqlDbWrapper { |
|
|
|
/** |
|
|
|
* Lock the type of a hd account |
|
|
|
* @param {string} xpub - xpub |
|
|
|
* @param {boolean} locked - true for locking, false for unlocking |
|
|
|
* @returns {boolean} locked - true for locking, false for unlocking |
|
|
|
*/ |
|
|
|
async setLockHDAccountType(xpub, locked) { |
|
|
|
locked = !!locked |
|
|
|
|
|
|
|
const account = await this.getHDAccount(xpub) |
|
|
|
const info = hdaHelper.classify(account.hdType) |
|
|
|
|
|
|
|
if (info.locked == locked) |
|
|
|
if (info.locked === locked) |
|
|
|
return true |
|
|
|
|
|
|
|
const hdType = hdaHelper.makeType(account.hdType, locked) |
|
|
@ -700,7 +699,7 @@ class MySqlDbWrapper { |
|
|
|
* Add an address a hd account |
|
|
|
* @param {string} address - bitcoin address |
|
|
|
* @param {string} xpub - xpub |
|
|
|
* @param {integer} chain - derivation chain |
|
|
|
* @param {number} chain - derivation chain |
|
|
|
* @param {index} index - derivation index for the address |
|
|
|
*/ |
|
|
|
async addAddressToHDAccount(address, xpub, chain, index) { |
|
|
@ -733,7 +732,7 @@ class MySqlDbWrapper { |
|
|
|
* which is the output of the HDAccountsHelper.deriveAddresses() |
|
|
|
*/ |
|
|
|
async addAddressesToHDAccount(xpub, addressData) { |
|
|
|
if (addressData.length == 0) |
|
|
|
if (addressData.length === 0) |
|
|
|
return |
|
|
|
|
|
|
|
const addresses = addressData.map(d => d.address) |
|
|
@ -769,7 +768,7 @@ class MySqlDbWrapper { |
|
|
|
* @returns {object[]} |
|
|
|
*/ |
|
|
|
async getUngroupedHDAccountsByAddresses(addresses) { |
|
|
|
if (addresses.length == 0) return {} |
|
|
|
if (addresses.length === 0) return {} |
|
|
|
|
|
|
|
const sqlQuery = 'SELECT \ |
|
|
|
`hd`.`hdID`, \ |
|
|
@ -814,7 +813,7 @@ class MySqlDbWrapper { |
|
|
|
loose: [] |
|
|
|
} |
|
|
|
|
|
|
|
if (addresses.length == 0) |
|
|
|
if (addresses.length === 0) |
|
|
|
return ret |
|
|
|
|
|
|
|
const sqlQuery = 'SELECT \ |
|
|
@ -865,7 +864,7 @@ class MySqlDbWrapper { |
|
|
|
/** |
|
|
|
* Get an HD account balance |
|
|
|
* @param {string} xpub - xpub |
|
|
|
* @returns {integer} returns the balance of the hd account |
|
|
|
* @returns {number} returns the balance of the hd account |
|
|
|
*/ |
|
|
|
async getHDAccountBalance(xpub) { |
|
|
|
const sqlQuery = 'SELECT \ |
|
|
@ -882,7 +881,7 @@ class MySqlDbWrapper { |
|
|
|
const query = mysql.format(sqlQuery, params) |
|
|
|
const results = await this._query(query) |
|
|
|
|
|
|
|
if (results.length == 1) |
|
|
|
if (results.length === 1) |
|
|
|
return (results[0].balance == null) ? 0 : results[0].balance |
|
|
|
|
|
|
|
return null |
|
|
@ -891,7 +890,7 @@ class MySqlDbWrapper { |
|
|
|
/** |
|
|
|
* Get next unused address indices for each HD chain of an account |
|
|
|
* @param {string} xpub - xpub |
|
|
|
* @returns {integer[]} returns an array of unused indices |
|
|
|
* @returns {number[]} returns an array of unused indices |
|
|
|
* [M/0/X, M/1/Y] -> [X,Y] |
|
|
|
*/ |
|
|
|
async getHDAccountNextUnusedIndices(xpub) { |
|
|
@ -921,7 +920,7 @@ class MySqlDbWrapper { |
|
|
|
/** |
|
|
|
* Get the maximum derived address index for each HD chain of an account |
|
|
|
* @param {string} xpub - xpub |
|
|
|
* @returns {integer[]} returns an array of derived indices |
|
|
|
* @returns {number[]} returns an array of derived indices |
|
|
|
* [M/0/X, M/1/Y] -> [X,Y] |
|
|
|
*/ |
|
|
|
async getHDAccountDerivedIndices(xpub) { |
|
|
@ -950,10 +949,10 @@ class MySqlDbWrapper { |
|
|
|
/** |
|
|
|
* Get the number of indices derived in an interval for a HD chain |
|
|
|
* @param {string} xpub - xpub |
|
|
|
* @param {integer} chain - HD chain (0 or 1) |
|
|
|
* @param {integer} minIdx - min index of derivation |
|
|
|
* @param {integer} maxIdx - max index of derivation |
|
|
|
* @returns {integer[]} returns an array of number of derived indices |
|
|
|
* @param {number} chain - HD chain (0 or 1) |
|
|
|
* @param {number} minIdx - min index of derivation |
|
|
|
* @param {number} maxIdx - max index of derivation |
|
|
|
* @returns {number[]} returns an array of number of derived indices |
|
|
|
*/ |
|
|
|
async getHDAccountNbDerivedIndices(xpub, chain, minIdx, maxIdx) { |
|
|
|
const sqlQuery = 'SELECT \ |
|
|
@ -969,7 +968,7 @@ class MySqlDbWrapper { |
|
|
|
const query = mysql.format(sqlQuery, params) |
|
|
|
const results = await this._query(query) |
|
|
|
|
|
|
|
if (results.length == 1) { |
|
|
|
if (results.length === 1) { |
|
|
|
const nbDerivedIndices = results[0].nbDerivedIndices |
|
|
|
return (nbDerivedIndices == null) ? 0 : nbDerivedIndices |
|
|
|
} |
|
|
@ -980,7 +979,7 @@ class MySqlDbWrapper { |
|
|
|
/** |
|
|
|
* Get the number of transactions for an HD account |
|
|
|
* @param {string} xpub - xpub |
|
|
|
* @returns {integer} returns the balance of the hd account |
|
|
|
* @returns {number} returns the balance of the hd account |
|
|
|
*/ |
|
|
|
async getHDAccountNbTransactions(xpub) { |
|
|
|
const sqlQuery = 'SELECT COUNT(DISTINCT `r`.`txnTxid`) AS nbTxs \ |
|
|
@ -1007,7 +1006,7 @@ class MySqlDbWrapper { |
|
|
|
const query = mysql.format(sqlQuery, params) |
|
|
|
const results = await this._query(query) |
|
|
|
|
|
|
|
if (results.length == 1) |
|
|
|
if (results.length === 1) |
|
|
|
return (results[0].nbTxs == null) ? 0 : results[0].nbTxs |
|
|
|
|
|
|
|
return null |
|
|
@ -1017,12 +1016,12 @@ class MySqlDbWrapper { |
|
|
|
* Get the number of transactions for a list of addresses and HD accounts |
|
|
|
* @param {string[]} addresses - array of bitcoin addresses |
|
|
|
* @param {string[]} xpubs - array of xpubs |
|
|
|
* @returns {int} returns the number of transactions |
|
|
|
* @returns {number} returns the number of transactions |
|
|
|
*/ |
|
|
|
async getAddrAndXpubsNbTransactions(addresses, xpubs) { |
|
|
|
if ( |
|
|
|
(!addresses || addresses.length == 0) |
|
|
|
&& (!xpubs || xpubs.length == 0) |
|
|
|
(!addresses || addresses.length === 0) |
|
|
|
&& (!xpubs || xpubs.length === 0) |
|
|
|
) { |
|
|
|
return [] |
|
|
|
} |
|
|
@ -1052,7 +1051,7 @@ class MySqlDbWrapper { |
|
|
|
let query = mysql.format(sqlQuery) |
|
|
|
const results = await this._query(query) |
|
|
|
|
|
|
|
if (results.length == 1) |
|
|
|
if (results.length === 1) |
|
|
|
return (results[0].nbTxs == null) ? 0 : results[0].nbTxs |
|
|
|
|
|
|
|
return null |
|
|
@ -1062,12 +1061,14 @@ class MySqlDbWrapper { |
|
|
|
* Get the transactions for a list of addresses and HD accounts |
|
|
|
* @param {string[]} addresses - array of bitcoin addresses |
|
|
|
* @param {string[]} xpubs - array of xpubs |
|
|
|
* @param {number=} page - page |
|
|
|
* @param {number=} nbTxsPerPage - number of transactions per page |
|
|
|
* @returns {object[]} returns an array of transactions |
|
|
|
*/ |
|
|
|
async getTxsByAddrAndXpubs(addresses, xpubs, page, nbTxsPerPage) { |
|
|
|
if ( |
|
|
|
(!addresses || addresses.length == 0) |
|
|
|
&& (!xpubs || xpubs.length == 0) |
|
|
|
(!addresses || addresses.length === 0) |
|
|
|
&& (!xpubs || xpubs.length === 0) |
|
|
|
) { |
|
|
|
return [] |
|
|
|
} |
|
|
@ -1117,7 +1118,7 @@ class MySqlDbWrapper { |
|
|
|
|
|
|
|
const txsIds = txs.map(t => t.txnID) |
|
|
|
|
|
|
|
if (txsIds.length == 0) |
|
|
|
if (txsIds.length === 0) |
|
|
|
return [] |
|
|
|
|
|
|
|
// Prepares subqueries for
|
|
|
@ -1189,7 +1190,7 @@ class MySqlDbWrapper { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (input.hdXpub && input.hdXpub !== null) { |
|
|
|
if (input.hdXpub) { |
|
|
|
ret.prev_out.xpub = { |
|
|
|
m: input.hdXpub, |
|
|
|
path: ['M', input.hdAddrChain, input.hdAddrIndex].join('/') |
|
|
@ -1211,7 +1212,7 @@ class MySqlDbWrapper { |
|
|
|
addr: output.outAddress |
|
|
|
} |
|
|
|
|
|
|
|
if (output.hdXpub && output.hdXpub !== null) { |
|
|
|
if (output.hdXpub) { |
|
|
|
ret.xpub = { |
|
|
|
m: output.hdXpub, |
|
|
|
path: ['M', output.hdAddrChain, output.hdAddrIndex].join('/') |
|
|
@ -1294,7 +1295,7 @@ class MySqlDbWrapper { |
|
|
|
async getXpubByAddresses(addresses) { |
|
|
|
const ret = {} |
|
|
|
|
|
|
|
if (addresses.length == 0) |
|
|
|
if (addresses.length === 0) |
|
|
|
return ret |
|
|
|
|
|
|
|
const sqlQuery = 'SELECT `hd`.`hdXpub`, `addresses`.`addrAddress` \ |
|
|
@ -1316,7 +1317,7 @@ class MySqlDbWrapper { |
|
|
|
/** |
|
|
|
* Get the mysql ID of a transaction. Ensures that the transaction exists. |
|
|
|
* @param {string} txid - txid of a transaction |
|
|
|
* @returns {integer} returns the transaction id (mysql id) |
|
|
|
* @returns {number} returns the transaction id (mysql id) |
|
|
|
*/ |
|
|
|
async ensureTransactionId(txid) { |
|
|
|
const sqlQuery = 'INSERT IGNORE INTO `transactions` SET ?' |
|
|
@ -1346,14 +1347,14 @@ class MySqlDbWrapper { |
|
|
|
/** |
|
|
|
* Get the mysql ID of a transaction |
|
|
|
* @param {string} txid - txid of a transaction |
|
|
|
* @returns {integer} returns the transaction id (mysql id) |
|
|
|
* @returns {number} returns the transaction id (mysql id) |
|
|
|
*/ |
|
|
|
async getTransactionId(txid) { |
|
|
|
const sqlQuery = 'SELECT `txnID` FROM `transactions` WHERE `txnTxid` = ?' |
|
|
|
const params = txid |
|
|
|
const query = mysql.format(sqlQuery, params) |
|
|
|
const result = await this._query(query) |
|
|
|
return (result.length == 0) ? null : result[0].txnID |
|
|
|
return (result.length === 0) ? null : result[0].txnID |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@ -1362,7 +1363,7 @@ class MySqlDbWrapper { |
|
|
|
* @returns {object[]} returns an array of {txnTxid: txnId} |
|
|
|
*/ |
|
|
|
async getTransactionsIds(txids) { |
|
|
|
if (txids.length == 0) |
|
|
|
if (txids.length === 0) |
|
|
|
return [] |
|
|
|
|
|
|
|
const sqlQuery = 'SELECT `txnID`, `txnTxid` FROM `transactions` WHERE `txnTxid` IN (?)' |
|
|
@ -1378,11 +1379,11 @@ class MySqlDbWrapper { |
|
|
|
|
|
|
|
/** |
|
|
|
* Get the mysql IDs of a set of transactions |
|
|
|
* @param {string[]} txid - array of transactions txids |
|
|
|
* @returns {integer[]} returns an array of transaction ids (mysql ids) |
|
|
|
* @param {string[]} txnIDs - array of transactions txids |
|
|
|
* @returns {number[]} returns an array of transaction ids (mysql ids) |
|
|
|
*/ |
|
|
|
async getTransactionsById(txnIDs) { |
|
|
|
if (txnIDs.length == 0) |
|
|
|
if (txnIDs.length === 0) |
|
|
|
return [] |
|
|
|
|
|
|
|
const sqlQuery = 'SELECT * FROM `transactions` WHERE `txnID` IN (?)' |
|
|
@ -1419,7 +1420,7 @@ class MySqlDbWrapper { |
|
|
|
* @param {object[]} txs - array of {txid, version, locktime} |
|
|
|
*/ |
|
|
|
async addTransactions(txs) { |
|
|
|
if (txs.length == 0) |
|
|
|
if (txs.length === 0) |
|
|
|
return |
|
|
|
|
|
|
|
const sqlQuery = 'INSERT INTO `transactions` \ |
|
|
@ -1567,10 +1568,10 @@ class MySqlDbWrapper { |
|
|
|
/** |
|
|
|
* Batch confirm txids in a block |
|
|
|
* @param {string[]} txnTxidArray - array of transaction txids |
|
|
|
* @param {integer} blockID - mysql id of the blck |
|
|
|
* @param {number} blockID - mysql id of the blck |
|
|
|
*/ |
|
|
|
async confirmTransactions(txnTxidArray, blockID) { |
|
|
|
if (txnTxidArray.length == 0) |
|
|
|
if (txnTxidArray.length === 0) |
|
|
|
return |
|
|
|
|
|
|
|
const sqlQuery = 'UPDATE `transactions` SET `blockID` = ? WHERE `txnTxid` IN (?)' |
|
|
@ -1581,8 +1582,8 @@ class MySqlDbWrapper { |
|
|
|
|
|
|
|
/** |
|
|
|
* Get the transactions confirmed after a given height |
|
|
|
* @param {integer]} height - block height |
|
|
|
* @param {object[]} returns an array of transactions |
|
|
|
* @param {number} height - block height |
|
|
|
* @returns {object[]} returns an array of transactions |
|
|
|
*/ |
|
|
|
async getTransactionsConfirmedAfterHeight(height) { |
|
|
|
const sqlQuery = 'SELECT `transactions`.* FROM `transactions` \ |
|
|
@ -1595,7 +1596,7 @@ class MySqlDbWrapper { |
|
|
|
|
|
|
|
/** |
|
|
|
* Delete the transactions confirmed after a given height |
|
|
|
* @param {integer]} height - block height |
|
|
|
* @param {number} height - block height |
|
|
|
*/ |
|
|
|
async deleteTransactionsConfirmedAfterHeight(height) { |
|
|
|
const sqlQuery = 'DELETE `transactions`.* FROM `transactions` \ |
|
|
@ -1611,7 +1612,7 @@ class MySqlDbWrapper { |
|
|
|
* @param {string[]} txnTxidArray - array of transaction txids |
|
|
|
*/ |
|
|
|
async unconfirmTransactions(txnTxidArray) { |
|
|
|
if (txnTxidArray.length == 0) |
|
|
|
if (txnTxidArray.length === 0) |
|
|
|
return |
|
|
|
|
|
|
|
const sqlQuery = 'UPDATE `transactions` SET `blockID` = NULL WHERE `txnTxid` IN (?)' |
|
|
@ -1633,10 +1634,10 @@ class MySqlDbWrapper { |
|
|
|
|
|
|
|
/** |
|
|
|
* Delete a set of transactions identified by their mysql ids |
|
|
|
* @param {integer[]} txnIDs - mysql ids of the transactions |
|
|
|
* @param {number[]} txnIDs - mysql ids of the transactions |
|
|
|
*/ |
|
|
|
async deleteTransactionsByID(txnIDs) { |
|
|
|
if (txnIDs.length == 0) |
|
|
|
if (txnIDs.length === 0) |
|
|
|
return [] |
|
|
|
|
|
|
|
const sqlQuery = 'DELETE `transactions`.* FROM `transactions` WHERE `transactions`.`txnID` in (?)' |
|
|
@ -1650,7 +1651,7 @@ class MySqlDbWrapper { |
|
|
|
* @param {object[]} outputs - array of {txnID, addrID, outIndex, outAmount, outScript} |
|
|
|
*/ |
|
|
|
async addOutputs(outputs) { |
|
|
|
if (outputs.length == 0) |
|
|
|
if (outputs.length === 0) |
|
|
|
return |
|
|
|
|
|
|
|
const sqlQuery = 'INSERT IGNORE INTO `outputs` \ |
|
|
@ -1671,7 +1672,7 @@ 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 = |
|
|
@ -1703,7 +1704,7 @@ class MySqlDbWrapper { |
|
|
|
* {outID, txnTxid, outIndex} |
|
|
|
*/ |
|
|
|
async getOutputIds(spends) { |
|
|
|
if (spends.length == 0) |
|
|
|
if (spends.length === 0) |
|
|
|
return [] |
|
|
|
|
|
|
|
const whereClauses = |
|
|
@ -1730,7 +1731,7 @@ class MySqlDbWrapper { |
|
|
|
* {txnTxid, outIndex, outAmount, outScript, addrAddress} |
|
|
|
*/ |
|
|
|
async getUnspentOutputs(addresses) { |
|
|
|
if (addresses.length == 0) |
|
|
|
if (addresses.length === 0) |
|
|
|
return [] |
|
|
|
|
|
|
|
const sqlQuery = 'SELECT \ |
|
|
@ -1761,7 +1762,7 @@ class MySqlDbWrapper { |
|
|
|
* {txnID, outID, inIndex, inSequence} |
|
|
|
*/ |
|
|
|
async addInputs(inputs) { |
|
|
|
if (inputs.length == 0) |
|
|
|
if (inputs.length === 0) |
|
|
|
return |
|
|
|
|
|
|
|
const sqlQuery = 'INSERT INTO `inputs` \ |
|
|
@ -1811,7 +1812,7 @@ class MySqlDbWrapper { |
|
|
|
const params = hash |
|
|
|
const query = mysql.format(sqlQuery, params) |
|
|
|
const result = await this._query(query) |
|
|
|
return (result.length == 1) ? result[0] : null |
|
|
|
return (result.length === 1) ? result[0] : null |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@ -1820,7 +1821,7 @@ class MySqlDbWrapper { |
|
|
|
* @returns {object[]} returns the blocks |
|
|
|
*/ |
|
|
|
async getBlocksByHashes(hashes) { |
|
|
|
if (hashes.length == 0) |
|
|
|
if (hashes.length === 0) |
|
|
|
return [] |
|
|
|
|
|
|
|
const sqlQuery = 'SELECT * FROM `blocks` WHERE `blockHash` IN (?)' |
|
|
@ -1831,7 +1832,7 @@ class MySqlDbWrapper { |
|
|
|
|
|
|
|
/** |
|
|
|
* Get details about all blocks at a given block height |
|
|
|
* @param {integer} height - block height |
|
|
|
* @param {number} height - block height |
|
|
|
* @returns {object[]} returns an array of blocks |
|
|
|
*/ |
|
|
|
async getBlocksByHeight(height) { |
|
|
@ -1843,7 +1844,7 @@ class MySqlDbWrapper { |
|
|
|
|
|
|
|
/** |
|
|
|
* Delete the blocks after a given block height |
|
|
|
* @param {integer} height - block height |
|
|
|
* @param {number} height - block height |
|
|
|
*/ |
|
|
|
async deleteBlocksAfterHeight(height) { |
|
|
|
const sqlQuery = 'DELETE FROM `blocks` WHERE `blockHeight` > ?' |
|
|
@ -1854,12 +1855,12 @@ class MySqlDbWrapper { |
|
|
|
|
|
|
|
/** |
|
|
|
* Gets the last block |
|
|
|
* @returns {object} returns the last block |
|
|
|
* @returns {object | null} returns the last block |
|
|
|
*/ |
|
|
|
async getHighestBlock() { |
|
|
|
try { |
|
|
|
const results = await this.getLastBlocks(1) |
|
|
|
if (results == null || results.length == 0) |
|
|
|
if (results == null || results.length === 0) |
|
|
|
return { |
|
|
|
blockID: null, |
|
|
|
blockHeight: 0 |
|
|
@ -1873,7 +1874,7 @@ class MySqlDbWrapper { |
|
|
|
|
|
|
|
/** |
|
|
|
* Gets the N last blocks |
|
|
|
* @param {integer} n - number of blocks to be retrieved |
|
|
|
* @param {number} n - number of blocks to be retrieved |
|
|
|
* @returns {object[]} returns an array of the n last blocks |
|
|
|
*/ |
|
|
|
async getLastBlocks(n) { |
|
|
@ -1896,14 +1897,14 @@ class MySqlDbWrapper { |
|
|
|
/** |
|
|
|
* Get the mysql ID of a scheduled transaction |
|
|
|
* @param {string} txid - txid of a scheduled transaction |
|
|
|
* @returns {integer} returns the scheduled transaction id (mysql id) |
|
|
|
* @returns {number} returns the scheduled transaction id (mysql id) |
|
|
|
*/ |
|
|
|
async getScheduledTransactionId(txid) { |
|
|
|
const sqlQuery = 'SELECT `schID` FROM `scheduled_transactions` WHERE `schTxid` = ?' |
|
|
|
const params = txid |
|
|
|
const query = mysql.format(sqlQuery, params) |
|
|
|
const result = await this._query(query) |
|
|
|
return (result.length == 0) ? null : result[0].txnID |
|
|
|
return (result.length === 0) ? null : result[0].txnID |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@ -1952,7 +1953,7 @@ class MySqlDbWrapper { |
|
|
|
/** |
|
|
|
* Get scheduled transactions |
|
|
|
* with a trigger lower than a given block height |
|
|
|
* @param {integer} height - block height |
|
|
|
* @param {number} height - block height |
|
|
|
*/ |
|
|
|
async getActivatedScheduledTransactions(height) { |
|
|
|
const sqlQuery = 'SELECT * FROM `scheduled_transactions` \ |
|
|
@ -1964,7 +1965,7 @@ class MySqlDbWrapper { |
|
|
|
|
|
|
|
/** |
|
|
|
* Get the scheduled transaction having a given parentID |
|
|
|
* @param {integer} parentId - parent ID |
|
|
|
* @param {number} parentId - parent ID |
|
|
|
* @returns {object[]} returns an array of scheduled transactions |
|
|
|
*/ |
|
|
|
async getNextScheduledTransactions(parentId) { |
|
|
@ -1978,8 +1979,8 @@ class MySqlDbWrapper { |
|
|
|
/** |
|
|
|
* Update the trigger of a scheduled transaction |
|
|
|
* identified by its ID |
|
|
|
* @param {integer} id - id of the scheduled transaction |
|
|
|
* @param {integer} trigger - new trigger |
|
|
|
* @param {number} id - id of the scheduled transaction |
|
|
|
* @param {number} trigger - new trigger |
|
|
|
*/ |
|
|
|
async updateTriggerScheduledTransaction(id, trigger) { |
|
|
|
const sqlQuery = 'UPDATE `scheduled_transactions` \ |
|
|
|