You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
116 lines
3.2 KiB
116 lines
3.2 KiB
/*!
|
|
* tracker/block.js
|
|
* Copyright © 2019 – Katana Cryptographic Ltd. All Rights Reserved.
|
|
*/
|
|
'use strict'
|
|
|
|
const bitcoin = require('bitcoinjs-lib')
|
|
const util = require('../lib/util')
|
|
const Logger = require('../lib/logger')
|
|
const db = require('../lib/db/mysql-db-wrapper')
|
|
const Transaction = require('./transaction')
|
|
const TransactionsBundle = require('./transactions-bundle')
|
|
|
|
|
|
/**
|
|
* A class allowing to process a transaction
|
|
*/
|
|
class Block extends TransactionsBundle {
|
|
|
|
/**
|
|
* Constructor
|
|
* @param {string} hex - block in hex format
|
|
* @param {string} header - block header
|
|
*/
|
|
constructor(hex, header) {
|
|
super()
|
|
this.hex = hex
|
|
this.header = header
|
|
}
|
|
|
|
/**
|
|
* Register the block and transactions of interest in db
|
|
* @returns {Promise - object[]} returns an array of transactions to be broadcast
|
|
*/
|
|
async checkBlock() {
|
|
Logger.info('Tracker : Beginning to process new block.')
|
|
|
|
let block
|
|
const txsForBroadcast = []
|
|
|
|
try {
|
|
block = bitcoin.Block.fromHex(this.hex)
|
|
this.transactions = block.transactions
|
|
} catch (e) {
|
|
Logger.error(e, 'Tracker : Block.checkBlock()')
|
|
Logger.error(null, this.header)
|
|
return Promise.reject(e)
|
|
}
|
|
|
|
const t0 = Date.now()
|
|
let ntx = 0
|
|
|
|
// Filter transactions
|
|
const filteredTxs = await this.prefilterTransactions()
|
|
|
|
// Check filtered transactions
|
|
// and broadcast notifications
|
|
await util.seriesCall(filteredTxs, async tx => {
|
|
const filteredTx = new Transaction(tx)
|
|
const txCheck = await filteredTx.checkTransaction()
|
|
if (txCheck && txCheck.broadcast)
|
|
txsForBroadcast.push(txCheck.tx)
|
|
})
|
|
|
|
// Retrieve the previous block
|
|
// and store the new block into the database
|
|
const prevBlock = await db.getBlockByHash(this.header.previousblockhash)
|
|
const prevID = (prevBlock && prevBlock.blockID) ? prevBlock.blockID : null
|
|
|
|
const blockId = await db.addBlock({
|
|
blockHeight: this.header.height,
|
|
blockHash: this.header.hash,
|
|
blockTime: this.header.time,
|
|
blockParent: prevID
|
|
})
|
|
|
|
Logger.info(`Tracker : Added block ${this.header.height} (id=${blockId})`)
|
|
|
|
// Confirms the transactions
|
|
const txids = this.transactions.map(t => t.getId())
|
|
ntx = txids.length
|
|
const txidLists = util.splitList(txids, 100)
|
|
await util.seriesCall(txidLists, list => db.confirmTransactions(list, blockId))
|
|
|
|
// Logs and result returned
|
|
const dt = ((Date.now()-t0)/1000).toFixed(1)
|
|
const per = ((Date.now()-t0)/ntx).toFixed(0)
|
|
Logger.info(`Tracker : Finished block ${this.header.height}, ${dt}s, ${ntx} tx, ${per}ms/tx`)
|
|
|
|
return txsForBroadcast
|
|
}
|
|
|
|
/**
|
|
* Register the block header
|
|
* @param {int} prevBlockID - id of previous block
|
|
* @returns {Promise}
|
|
*/
|
|
async checkBlockHeader(prevBlockID) {
|
|
Logger.info('Tracker : Beginning to process new block header.')
|
|
|
|
// Insert the block header into the database
|
|
const blockId = await db.addBlock({
|
|
blockHeight: this.header.height,
|
|
blockHash: this.header.hash,
|
|
blockTime: this.header.time,
|
|
blockParent: prevBlockID
|
|
})
|
|
|
|
Logger.info(`Tracker : Added block header ${this.header.height} (id=${blockId})`)
|
|
|
|
return blockId
|
|
}
|
|
|
|
}
|
|
|
|
module.exports = Block
|
|
|