Browse Source

updates:

fixed #4,
add block processing timer,
add hashrate fetcher, add it to block table model,
updated index page output, increase output to 50 rows,
updated database block table datatypes
master
R4SAS 5 years ago committed by R4SAS
parent
commit
6108749fdd
  1. 35
      bin/syncBlockchain.js
  2. 4
      models/address.js
  3. 19
      models/block.js
  4. 8
      routes/index.js
  5. 18
      views/index.pug
  6. 2
      views/transaction.pug

35
bin/syncBlockchain.js

@ -11,7 +11,8 @@ const keepAliveAgent = new http.Agent({ keepAlive: true });
let sync_sql = '', let sync_sql = '',
coolstrs = []; coolstrs = [],
starttime = 0;
function MakeRPCRequest(postData) { function MakeRPCRequest(postData) {
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
@ -82,7 +83,7 @@ async function saveTransaction(txid, blockHeight) {
SET @txid = LAST_INSERT_ID(); SET @txid = LAST_INSERT_ID();
`; `;
// Loop over vouts // Loop over vout's
for (var i = 0; i < tx.vout.length; i++) { for (var i = 0; i < tx.vout.length; i++) {
const vout = tx.vout[i]; const vout = tx.vout[i];
@ -136,7 +137,7 @@ async function saveTransaction(txid, blockHeight) {
`; `;
} }
// Loop over vins // Loop over vin's
for (var i = 0; i < tx.vin.length; i++) { for (var i = 0; i < tx.vin.length; i++) {
const vin = tx.vin[i]; const vin = tx.vin[i];
if (vin.txid) { if (vin.txid) {
@ -186,6 +187,7 @@ async function syncNextBlock(syncedHeight) {
id: 1 id: 1
})); }));
const blockHash = JSON.parse(res_hash)['result']; const blockHash = JSON.parse(res_hash)['result'];
const res_block = await MakeRPCRequest(JSON.stringify({ const res_block = await MakeRPCRequest(JSON.stringify({
method: 'getblock', method: 'getblock',
params: [blockHash], params: [blockHash],
@ -193,6 +195,13 @@ async function syncNextBlock(syncedHeight) {
})); }));
const block = JSON.parse(res_block)['result']; const block = JSON.parse(res_block)['result'];
const res_blockhr = await MakeRPCRequest(JSON.stringify({
method: 'getnetworkhashps',
params: [120, height],
id: 1
}));
block.hashrate = JSON.parse(res_blockhr)['result'];
block.time = moment(block.time*1000).format('YYYY-MM-DD HH:mm:ss'); block.time = moment(block.time*1000).format('YYYY-MM-DD HH:mm:ss');
// await models.Block.create(block); // await models.Block.create(block);
@ -209,8 +218,8 @@ async function syncNextBlock(syncedHeight) {
nonce, nonce,
bits, bits,
difficulty, difficulty,
previousblockhash, hashrate,
nextblockhash previousblockhash
) )
VALUES ( VALUES (
"${block.hash}", "${block.hash}",
@ -222,8 +231,8 @@ async function syncNextBlock(syncedHeight) {
"${block.nonce}", "${block.nonce}",
"${block.bits}", "${block.bits}",
"${block.difficulty}", "${block.difficulty}",
"${block.previousblockhash}", "${block.hashrate}",
"${block.nextblockhash}" "${block.previousblockhash}"
); );
` `
coolstrs = [] coolstrs = []
@ -243,8 +252,8 @@ async function syncNextBlock(syncedHeight) {
// }); // });
sync_sql += ` sync_sql += `
UPDATE Block UPDATE Block
SET nextblockhash="${block.previousblockhash}" SET nextblockhash="${block.hash}"
WHERE nextblockhash="${block.previousblockhash}"; WHERE hash="${block.previousblockhash}";
` `
} }
sync_sql += 'COMMIT;' sync_sql += 'COMMIT;'
@ -283,7 +292,7 @@ async function acquireLock() {
} else { } else {
console.log('Could\'nt lock file', ex); console.log('Could\'nt lock file', ex);
} }
throw ex; process.exit(0);
} }
} }
@ -300,10 +309,11 @@ async function syncBlockchain() {
console.log('\x1b[34m%s\x1b[0m', 'currentHeight is', currentHeight); console.log('\x1b[34m%s\x1b[0m', 'currentHeight is', currentHeight);
while (syncedHeight < currentHeight) { while (syncedHeight < currentHeight) {
starttime = new Date().getTime();
syncedHeight = await syncNextBlock(syncedHeight); syncedHeight = await syncNextBlock(syncedHeight);
if (coolstrs) { if (coolstrs) {
for(str of coolstrs) { for(str of coolstrs) {
console.log('\x1b[36m%s\x1b[0m', `syncedHeight: ${syncedHeight}/${currentHeight}`, str) console.log('\x1b[36m%s\x1b[0m', `syncedHeight: ${syncedHeight}/${currentHeight}`, str, ' [', new Date().getTime() - starttime, 'ms ]')
} }
} else { } else {
console.log('\x1b[36m%s\x1b[0m', 'syncedHeight: ', syncedHeight) console.log('\x1b[36m%s\x1b[0m', 'syncedHeight: ', syncedHeight)
@ -312,7 +322,8 @@ async function syncBlockchain() {
} catch (e) { } catch (e) {
console.log(e); console.log(e);
} finally { } finally {
models.sequelize.close().then(() => process.exit(0)); await models.sequelize.close();
process.exit(0);
} }
} }

4
models/address.js

@ -14,8 +14,8 @@ module.exports = (sequelize, DataTypes) => {
const AddressVout = sequelize.define('AddressVout', {}, { timestamps: false }); const AddressVout = sequelize.define('AddressVout', {}, { timestamps: false });
Address.associate = function (models) { Address.associate = function (models) {
models.Address.belongsToMany(models.Vout, { through: 'AddressVout' }); models.Address.belongsToMany(models.Vout, { through: 'AddressVout' });
}; };
return Address; return Address;
}; };

19
models/block.js

@ -1,25 +1,26 @@
'use strict'; 'use strict';
module.exports = (sequelize, DataTypes) => { module.exports = (sequelize, DataTypes) => {
const Block = sequelize.define('Block', { const Block = sequelize.define('Block', {
height: { height: {
type: DataTypes.INTEGER.UNSIGNED, type: DataTypes.INTEGER.UNSIGNED,
primaryKey: true, primaryKey: true,
}, },
hash: DataTypes.STRING(64), hash: DataTypes.STRING(64),
size: DataTypes.MEDIUMINT.UNSIGNED, size: DataTypes.MEDIUMINT.UNSIGNED,
version: DataTypes.TINYINT.UNSIGNED, version: DataTypes.TINYINT.UNSIGNED,
merkleroot: DataTypes.STRING(64), merkleroot: DataTypes.STRING(64),
time: DataTypes.DATE, time: DataTypes.DATE,
nonce: DataTypes.BIGINT, nonce: DataTypes.BIGINT.UNSIGNED,
bits: DataTypes.STRING(8), bits: DataTypes.STRING(8),
difficulty: DataTypes.DECIMAL(16, 8), difficulty: DataTypes.DECIMAL(16, 8).UNSIGNED,
hashrate: DataTypes.BIGINT.UNSIGNED,
previousblockhash: DataTypes.STRING(64), previousblockhash: DataTypes.STRING(64),
nextblockhash: DataTypes.STRING(64), nextblockhash: DataTypes.STRING(64),
}, { }, {
timestamps: false, timestamps: false,
indexes: [{ indexes: [{
unique: true, unique: true,
fields: ['hash', 'height'] fields: ['hash', 'height']
}], }],
freezeTableName: true, freezeTableName: true,
}); });
@ -29,4 +30,4 @@ module.exports = (sequelize, DataTypes) => {
}; };
return Block; return Block;
}; };

8
routes/index.js

@ -6,9 +6,13 @@ var router = express.Router();
router.get('/', async function(req, res, next) { router.get('/', async function(req, res, next) {
const blocks = await models.Block.findAll({ const blocks = await models.Block.findAll({
attributes: ['height', 'hash'], attributes: ['height', 'hash', 'time', 'difficulty', 'hashrate'],
order: [['height', 'DESC']], order: [['height', 'DESC']],
limit: 30, limit: 50,
});
blocks.forEach(function(arrayItem) {
arrayItem.ago = arrayItem.time.toUTCString().substring(5);
arrayItem.difficulty = arrayItem.difficulty.toFixed(8);
}); });
res.render('index', { res.render('index', {
blocks, blocks,

18
views/index.pug

@ -1,11 +1,25 @@
extends layout extends layout
block content block content
h3 Last 30 blocks h3 Last 50 blocks
table table
tr
td
b Height
td
b Time
td
b Difficulty
td
b Hashrate
td
b Hash
each block in blocks each block in blocks
tr tr
td #{block.height} td #{block.height} -
td #{block.ago} -
td #{block.difficulty} -
td #{block.hashrate} -
td td
a(href='/block/' + block.hash + '/') #{block.hash} a(href='/block/' + block.hash + '/') #{block.hash}

2
views/transaction.pug

@ -55,4 +55,4 @@ block content
td #{vout.value} td #{vout.value}
td td
each transaction in vout.Transactions each transaction in vout.Transactions
a(href=`/transaction/${transaction.txid}/`) #{transaction.txid} a(href=`/transaction/${transaction.txid}/`) #{transaction.txid}

Loading…
Cancel
Save