account_info_db.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. const logger = require('../logger')
  2. var { db_config } = require('../../config/config.js')
  3. const utils = require('../utils.js')
  4. var mysql = require('mysql');
  5. const redis = require("./redis_db") //导入 db.js
  6. var port = db_config.mysql.PORT
  7. var host = db_config.mysql.HOST
  8. var username = db_config.mysql.USERNAME
  9. var password = db_config.mysql.PASSWORD
  10. var database = db_config.mysql.DATABASE_MY_NODE
  11. var open_pool = db_config.mysql.OPEN_POOL
  12. var pool_size = db_config.mysql.POOL_SIZE
  13. var opts = {
  14. host: host,
  15. user: username,
  16. password: password,
  17. port: port,
  18. database: database,
  19. }
  20. var MYSQL_INSTANCE = null;
  21. //程序启动默认创建一个 mysql 连接
  22. createDefMysqlConnect();
  23. // 开始创建
  24. function createDefMysqlConnect() {
  25. disDefMysqlConnect();
  26. logger.log('createDefMysqlConnect', database)
  27. if (open_pool) {//创建连接池
  28. opts.connectionLimit = pool_size
  29. MYSQL_INSTANCE = mysql.createPool(opts);
  30. addConnEvent()
  31. } else {//创建单连接
  32. MYSQL_INSTANCE = mysql.createConnection(opts);
  33. addConnEvent()
  34. MYSQL_INSTANCE.connect();
  35. }
  36. return MYSQL_INSTANCE;
  37. }
  38. //关闭 mysql
  39. function disDefMysqlConnect() {
  40. if (MYSQL_INSTANCE) {
  41. if (open_pool) {
  42. MYSQL_INSTANCE.end();
  43. } else {
  44. MYSQL_INSTANCE.end();
  45. }
  46. MYSQL_INSTANCE = null;
  47. logger.debug('disDefMysqlConnect')
  48. }
  49. }
  50. function getMySqlInstance() {
  51. if (MYSQL_INSTANCE) return MYSQL_INSTANCE
  52. return createDefMysqlConnect();
  53. }
  54. function addConnEvent() {
  55. if (!MYSQL_INSTANCE) return
  56. if (open_pool) {
  57. MYSQL_INSTANCE.on('acquire', function (connection) {
  58. logger.log('Connection %d acquired', connection.threadId);
  59. });
  60. MYSQL_INSTANCE.on('connection', function (connection) {
  61. logger.log('mysql connection', connection.threadId);
  62. });
  63. MYSQL_INSTANCE.on('enqueue', function () {
  64. logger.log('Waiting for available connection slot');
  65. });
  66. MYSQL_INSTANCE.on('release', function (connection) {
  67. logger.log('Connection %d released', connection.threadId);
  68. });
  69. } else {
  70. // logger.log('connected to mysql ps=', db_config.mysql)
  71. MYSQL_INSTANCE.on('connect', () => {
  72. logger.log('connected to mysql')
  73. })
  74. MYSQL_INSTANCE.on('error', function (err) {
  75. logger.error('mysql Error =>', err);
  76. });
  77. MYSQL_INSTANCE.on('restart', function () {
  78. logger.error('mysql restart =>');
  79. });
  80. }
  81. }
  82. async function getAccountBalances_(opts) {
  83. logger.log('getAccountBalances', opts)
  84. opts.chain = utils.getChainNameFromChain(opts.chain)
  85. var sql_main = 'select * from '
  86. var sql_table_name = ' user_balance '
  87. var sql_where = ' WHERE '
  88. var sql_where_name = ' usr_address=? AND chain=? ORDER BY update_tm DESC '
  89. var query_account_balances_params = [opts.address, opts.chain]
  90. if (opts.type == 'native') {
  91. sql_where_name = ' usr_address=? AND token_address=? AND chain=? ORDER BY update_tm DESC '
  92. query_account_balances_params = [opts.address, '0x0000000000000000000000000000000000000000', opts.chain]
  93. } else if (opts.type == 'token') {
  94. sql_where_name = ' usr_address=? AND token_address!=? AND chain=? ORDER BY update_tm DESC '
  95. query_account_balances_params = [opts.address, '0x0000000000000000000000000000000000000000', opts.chain]
  96. }
  97. var new_sql = sql_main.concat(sql_table_name, sql_where, sql_where_name);
  98. var query_account_balances_sql = new_sql
  99. return new Promise((resolve) => {
  100. getMySqlInstance().getConnection(function (err, connection) {
  101. if (err) {
  102. logger.error('getAccountBalances_ error', err)
  103. logger.error('getAccountBalances_ sql', create_withdraw_sql)
  104. resolve(null);
  105. return;
  106. }
  107. connection.query(
  108. query_account_balances_sql, query_account_balances_params,
  109. function selectCb(error, results) {
  110. if (error) {
  111. logger.error('getAccountBalances_', error, query_account_balances_sql, query_account_balances_params)
  112. resolve(null);
  113. return;
  114. }
  115. logger.log('getAccountBalances_ ret=', error, results);
  116. //用完当前连接需要释放,归还给连接池
  117. connection.release();
  118. resolve({
  119. results: results
  120. });
  121. }
  122. );
  123. })
  124. })
  125. }
  126. async function getAccountTransactions_(opts) {
  127. logger.log('getAccountTransactions', opts)
  128. var sql_main = 'select * from '
  129. var sql_table_name = ' user_transaction_log '
  130. var sql_where = ' WHERE '
  131. var sql_where_name = ' usr_to_address=? AND block_num>=? AND chain=? '
  132. var query_account_transactions_params = [opts.address, opts.from_block ? opts.from_block : 1, opts.chain]
  133. if (opts.type == 'native') {
  134. sql_where_name = ' usr_to_address=? AND block_num>=? AND token_address=? AND chain=? '
  135. query_account_transactions_params = [opts.address, opts.from_block ? opts.from_block : 1, '0x0000000000000000000000000000000000000000', opts.chain]
  136. } else if (opts.type == 'token') {
  137. sql_where_name = ' usr_to_address=? AND block_num>=? AND token_address!=? AND chain=? '
  138. query_account_transactions_params = [opts.address, opts.from_block ? opts.from_block : 1, '0x0000000000000000000000000000000000000000', opts.chain]
  139. } else if (opts.type == 'hash') {
  140. sql_where_name = ' trx_hash=? AND chain=? '
  141. query_account_transactions_params = [opts.transaction_hash, opts.chain]
  142. } else if (opts.type == 'only_hash') {
  143. sql_where_name = ' trx_hash=? '
  144. query_account_transactions_params = [opts.transaction_hash]
  145. }
  146. var new_sql = sql_main.concat(sql_table_name, sql_where, sql_where_name);
  147. var query_account_transactions_sql = new_sql
  148. logger.log('getAccountTransactions new_sql', new_sql)
  149. logger.log('getAccountTransactions query_account_transactions_params', query_account_transactions_params)
  150. return new Promise((resolve) => {
  151. getMySqlInstance().getConnection(function (err, connection) {
  152. if (err) {
  153. logger.error('getAccountTransactions_', err)
  154. logger.error('getAccountTransactions_', query_account_transactions_sql)
  155. resolve(null);
  156. return;
  157. }
  158. connection.query(
  159. query_account_transactions_sql, query_account_transactions_params,
  160. function selectCb(error, results) {
  161. if (error) {
  162. logger.error('getAccountTransactions_', error, query_account_transactions_sql, query_account_transactions_params)
  163. resolve(null);
  164. return;
  165. }
  166. //用完当前连接需要释放,归还给连接池
  167. connection.release();
  168. resolve({
  169. results: results
  170. });
  171. }
  172. );
  173. })
  174. })
  175. }
  176. async function getAccountBalances(opts) {
  177. var ret = await getAccountBalances_(opts);
  178. var results = []
  179. if (ret && ret.results) {
  180. if (ret.results && Array.isArray(ret.results) && ret.results.length > 0) {
  181. for (let index = 0; index < ret.results.length; index++) {
  182. const element = ret.results[index];
  183. if (element.token_address == '0x0000000000000000000000000000000000000000') {
  184. //
  185. results.push({
  186. type: 'native',
  187. balance: utils.scientificNotationToString(element.balance).toString(),
  188. responseType: 'yqcx'
  189. })
  190. } else {
  191. // {
  192. // token_address: '0x03716f32f72c692a0b355fa04639669e3341b94e',
  193. // name: 'BF_BSC_XXXXXX',
  194. // symbol: 'BSC_BF_6X',
  195. // logo: null,
  196. // thumbnail: null,
  197. // decimals: 18,
  198. // balance: '1000000000000000000000'
  199. // }
  200. var decimals = 18
  201. try {
  202. // decimals = await redis.readRedis('REDIS_ERC20_CONTRACT_DECIMALS_' + element.token_address.toLowerCase())
  203. decimals = await redis.readAppendRedis('REDIS_ERC20_CONTRACT_DECIMALS', opts.chain, element.token_address.toLowerCase())
  204. } catch (error) {
  205. decimals=18
  206. }
  207. results.push({
  208. type: 'token',
  209. token_address: element.token_address,
  210. balance: utils.scientificNotationToString(element.balance).toString(),
  211. decimals: parseInt(decimals),
  212. responseType: 'yqcx'
  213. })
  214. }
  215. }
  216. }
  217. }
  218. return {
  219. code: 0,
  220. data: {
  221. total: results.length,
  222. results: results
  223. }
  224. }
  225. }
  226. async function getAccountTransactions(opts) {
  227. var ret = await getAccountTransactions_(opts);
  228. if (ret && ret.results) {
  229. if (ret.results && Array.isArray(ret.results) && ret.results.length > 0) {
  230. try {
  231. var results = []
  232. ret.results.forEach(element => {
  233. var isNativeTrans = element.token_address == '0x0000000000000000000000000000000000000000'
  234. element.type = isNativeTrans == true ? 'native' : 'token'
  235. element.gas = element.gas.toString()
  236. element.gas_price = element.gas_price.toString()
  237. try {
  238. element.value = utils.scientificNotationToString(element.value).toString()
  239. } catch (error) {
  240. element.value = element.value.toString();
  241. }
  242. logger.log('getAccountTransactions_ element:', element)
  243. results.push({
  244. type: isNativeTrans == true ? 'native' : 'token',
  245. from_address: element.usr_from_address,
  246. to_address: element.usr_to_address,
  247. token_address: isNativeTrans == false ? element.token_address : null,
  248. block_number: element.block_num.toString(),
  249. value: element.value,
  250. gas: element.gas,
  251. gas_price: element.gas_price,
  252. block_timestamp: utils.getTimestampToDate(element.block_tm * 1000),
  253. trx_hash: element.trx_hash,
  254. responseType: 'yqcx'
  255. })
  256. });
  257. ret.results = results
  258. } catch (error) {
  259. }
  260. logger.log('getAccountTransactions_ respose:', ret)
  261. return {
  262. code: 0,
  263. data: {
  264. total: ret.results.length,
  265. results: ret.results
  266. },
  267. errMsg: null,
  268. }
  269. }
  270. }
  271. return {
  272. code: 0,
  273. data: {
  274. total: 0,
  275. results: []
  276. },
  277. errMsg: null,
  278. }
  279. }
  280. module.exports = {
  281. getAccountBalances,
  282. getAccountTransactions,
  283. }