From d86beee960b5a714e4509b4d5acea2f588ed88e9 Mon Sep 17 00:00:00 2001 From: Joe Uhren Date: Tue, 6 Feb 2024 19:44:11 -0700 Subject: [PATCH] Add new settings to save+display multi-algo data -New settings allow reading of the hash algorithm used to mine a particular block for coins that support this feature and have the algorithm data stored in the raw block data -An "Algorithm" column has been added to the block page and main transaction homepage when multi-algo data is enabled -The /ext/getlasttxs api will now return the hash algorithm if reading of the multi-algo data is enabled --- README.md | 2 +- lib/database.js | 34 +++++++++++++++++++++++++++------- lib/settings.js | 13 ++++++++++++- models/tx.js | 3 ++- scripts/benchmark.js | 2 +- scripts/sync.js | 4 ++-- settings.json.template | 13 ++++++++++++- views/block.pug | 4 ++++ views/index.pug | 24 ++++++++++++++++++------ 9 files changed, 79 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 253ba331..48b5c10f 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ Table of Contents - **getmasternoderewardstotal:** Returns the total number of coins earned in masternode rewards for a specific address that arrived after a specific block height *\*only applicable to masternode coins* - **Claim Address:** Allows anyone to set custom display names for wallet addresses that they own using the **Sign Message** feature from their local wallet. Includes *bad word* filter support. - **Orphaned Blocks:** Displays a list of orphaned blocks with links to the next and previous "good" blocks - - **Block Info:** Displays block summary and list of transactions for a specific block height + - **Block Info:** Displays block summary and list of transactions for a specific block height along with optional hash algorithm for multi-algo coins - **Transaction Info:** Displays transaction summary, optional OP_RETURN value, list of input addresses and output addresses for a specific transaction - **Address Info:** Displays wallet address summary (balance, total sent, total received, QR code) and a list of latest transactions for a specific wallet address - Choose from 26 built-in themes with tweakable settings such as light and dark options to customize the look and feel of the explorer: diff --git a/lib/database.js b/lib/database.js index 91d5eeff..a6cd0519 100644 --- a/lib/database.js +++ b/lib/database.js @@ -590,10 +590,13 @@ module.exports = { if (tx) { // collection has data // determine if tx_type field exists - check_add_db_field(Tx, 'tx_type', null, function(exists) { + check_add_db_field(Tx, 'tx_type', null, function() { // determine if op_return field exists - check_add_db_field(Tx, 'op_return', null, function(exists) { - return cb(true); + check_add_db_field(Tx, 'op_return', null, function() { + // determine if algo field exists + check_add_db_field(Tx, 'algo', null, function() { + return cb(true); + }); }); }); } else @@ -882,16 +885,24 @@ module.exports = { row.push((txs[i].total / 100000000)); row.push(txs[i].timestamp); + if (settings.block_page.multi_algorithm.show_algo == true) + row.push('algo:' + (txs[i].algo == null ? '' : txs[i].algo)); + data.push(row); } else { - data.push({ + let data_entry = { blockindex: txs[i].blockindex, blockhash: txs[i].blockhash, txid: txs[i].txid, recipients: txs[i].vout.length, amount: (txs[i].total / 100000000), timestamp: txs[i].timestamp - }); + }; + + if (settings.block_page.multi_algorithm.show_algo == true) + data_entry.algo = (txs[i].algo == null ? '' : txs[i].algo); + + data.push(data_entry); } } @@ -1931,7 +1942,7 @@ module.exports = { } }, - save_tx: function(txid, blockheight, cb) { + save_tx: function(txid, blockheight, block, cb) { lib.get_rawtransaction(txid, function(tx) { if (tx && tx != 'There was an error. Check your console.') { lib.prepare_vin(tx, function(vin, tx_type_vin) { @@ -1967,6 +1978,8 @@ module.exports = { }, function() { lib.calculate_total(vout, function(total) { var op_return = null; + var algo = null; + // check if the op_return value should be decoded and saved if (settings.transaction_page.show_op_return) { // loop through vout to find the op_return value @@ -1979,6 +1992,12 @@ module.exports = { }); } + // check if the algo value should be saved + if (settings.block_page.multi_algorithm.show_algo) { + // get the algo value + algo = block[settings.block_page.multi_algorithm.key_name]; + } + var newTx = new Tx({ txid: tx.txid, vin: (vin == null || vin.length == 0 ? [] : nvin), @@ -1988,7 +2007,8 @@ module.exports = { blockhash: tx.blockhash, blockindex: blockheight, tx_type: (tx_type_vout == null ? tx_type_vin : tx_type_vout), - op_return: op_return + op_return: op_return, + algo: algo }); newTx.save().then(() => { diff --git a/lib/settings.js b/lib/settings.js index 55159671..5f99e725 100644 --- a/lib/settings.js +++ b/lib/settings.js @@ -498,7 +498,18 @@ exports.block_page = { // genesis_block: Your coins genesis block hash is used to determine the beginning of the blockchain // For many bitcoin clones you can use the following cmd to get the block hash of the genesis block: coin-cli getblockhash 0 // NOTE: If this value is not entered correctly it will not be possible for the explorer to find or navigate to the genesis block, neither via block or transaction hash - "genesis_block": "00014f36c648cdbc750f7dd28487a23cd9e0b0f95f5fccc5b5d01367e3f57469" + "genesis_block": "00014f36c648cdbc750f7dd28487a23cd9e0b0f95f5fccc5b5d01367e3f57469", + // multi_algorithm: a collection of settings that can be used to show a new column with the hash algorithm that was used to mine a particular block for multi-algo coins + // If enabled, a new column will be displayed on the block page and main transaction homepage that displays the hash algorithm used to mine a particular block or tx + // NOTE: Changing any of the options in this section will require a full reindex of the blockchain data before previously synced blocks can display the algorithm + "multi_algorithm": { + // show_algo: Determine whether to read and display the hash algorithm that was used to mine a particular block for multi-algo coins + // NOTE: Enabling this option will require a full reindex of the blockchain data before previously synced blocks can display the algorithm + "show_algo": false, + // key_name: The name of the key or identifier in the raw block data that determines which hash algorithm was used to mine a particular block + // NOTE: Changing this option will require a full reindex of the blockchain data before previously synced blocks can display the algorithm + "key_name": "pow_algo" + } }; // transaction_page: a collection of settings that pertain to the transaction/tx page diff --git a/models/tx.js b/models/tx.js index 6a14a60e..50e96ba2 100644 --- a/models/tx.js +++ b/models/tx.js @@ -10,7 +10,8 @@ var TxSchema = new Schema({ blockhash: { type: String, index: true }, blockindex: {type: Number, default: 0, index: true}, tx_type: { type: String, default: null }, - op_return: { type: String, default: null } + op_return: { type: String, default: null }, + algo: { type: String, default: null } }, {id: false}); TxSchema.index({total: 1, total: -1, blockindex: 1, blockindex: -1}); diff --git a/scripts/benchmark.js b/scripts/benchmark.js index bc10fb2f..fa9e3a0f 100644 --- a/scripts/benchmark.js +++ b/scripts/benchmark.js @@ -66,7 +66,7 @@ mongoose.connect(dbString).then(() => { next_tx(); }, timeout); } else { - db.save_tx(txid, block_height, function(err, tx_has_vout) { + db.save_tx(txid, block_height, block, function(err, tx_has_vout) { if (err) console.log(err); else diff --git a/scripts/sync.js b/scripts/sync.js index c48fed63..55c6481d 100644 --- a/scripts/sync.js +++ b/scripts/sync.js @@ -120,7 +120,7 @@ function update_tx_db(coin, start, end, txes, timeout, check_only, cb) { // check if this tx should be added to the local database if (tx_deleted || !tx) { // save the transaction to local database - db.save_tx(txid, block_height, function(err, tx_has_vout) { + db.save_tx(txid, block_height, block, function(err, tx_has_vout) { if (err) console.log(err); else @@ -673,7 +673,7 @@ function check_add_tx(txid, blockhash, tx_count, cb) { // check if the block was found if (block) { // save the tx to the local database - db.save_tx(txid, block.height, function(save_tx_err, tx_has_vout) { + db.save_tx(txid, block.height, block, function(save_tx_err, tx_has_vout) { // check if there were any save errors if (save_tx_err) console.log(save_tx_err); diff --git a/settings.json.template b/settings.json.template index eae98c03..b0f68636 100644 --- a/settings.json.template +++ b/settings.json.template @@ -582,7 +582,18 @@ // genesis_block: Your coins genesis block hash is used to determine the beginning of the blockchain // For many bitcoin clones you can use the following cmd to get the block hash of the genesis block: coin-cli getblockhash 0 // NOTE: If this value is not entered correctly it will not be possible for the explorer to find or navigate to the genesis block, neither via block or transaction hash - "genesis_block": "00014f36c648cdbc750f7dd28487a23cd9e0b0f95f5fccc5b5d01367e3f57469" + "genesis_block": "00014f36c648cdbc750f7dd28487a23cd9e0b0f95f5fccc5b5d01367e3f57469", + // multi_algorithm: a collection of settings that can be used to show a new column with the hash algorithm that was used to mine a particular block for multi-algo coins + // If enabled, a new column will be displayed on the block page and main transaction homepage that displays the hash algorithm used to mine a particular block or tx + // NOTE: Changing any of the options in this section will require a full reindex of the blockchain data before previously synced blocks can display the algorithm + "multi_algorithm": { + // show_algo: Determine whether to read and display the hash algorithm that was used to mine a particular block for multi-algo coins + // NOTE: Enabling this option will require a full reindex of the blockchain data before previously synced blocks can display the algorithm + "show_algo": false, + // key_name: The name of the key or identifier in the raw block data that determines which hash algorithm was used to mine a particular block + // NOTE: Changing this option will require a full reindex of the blockchain data before previously synced blocks can display the algorithm + "key_name": "pow_algo" + } }, // transaction_page: a collection of settings that pertain to the transaction/tx page diff --git a/views/block.pug b/views/block.pug index 88a85ffe..4174b71d 100644 --- a/views/block.pug +++ b/views/block.pug @@ -75,6 +75,8 @@ block content tr(class=theadClasses) th.text-center #{settings.locale.height} th.text-center #{settings.locale.difficulty} + if settings.block_page.multi_algorithm.show_algo == true + th.text-center='Algorithm' th.text-center #{settings.locale.confirmations} if settings.blockchain_specific.heavycoin.enabled == true th.text-center Vote @@ -91,6 +93,8 @@ block content td.text-center=block.height td.text-center #{splitDifficulty[0]}. span.decimal #{splitDifficulty[1]} + if settings.block_page.multi_algorithm.show_algo == true + td.text-center=block[settings.block_page.multi_algorithm.key_name] if block.confirmations >= confirmations td.text-center.table-success=block.confirmations else if block.confirmations < (confirmations / 2) diff --git a/views/index.pug b/views/index.pug index cd3abbd6..c47c7e78 100644 --- a/views/index.pug +++ b/views/index.pug @@ -61,20 +61,30 @@ block content } }, rowCallback: function(row, data, index) { - var blockindex = data[0]; //variables for better readability - var blockhash = data[1]; //variables for better readability - var txhash = data[2]; //variables for better readability - var outputs = data[3]; //variables for better readability - var amount = Number(data[4]).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); //variables for better readability + // variables for better readability + var blockindex = data[0]; + var blockhash = data[1]; + var txhash = data[2]; + var outputs = data[3]; + var amount = Number(data[4]).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); var amountParts = amount.split('.'); var amount = amountParts[0] + '.' + amountParts[1] + ''; var timestamp = data[5]; + var offset = 0; + $("td:eq(0)", row).html('').addClass('text-center d-table-cell d-md-none'); $("td:eq(1)", row).html('' + blockindex + ''); $("td:eq(2)", row).html('' + txhash + '').addClass("text-center breakWord d-none d-md-table-cell"); $("td:eq(3)", row).html(outputs).addClass("text-center d-none d-sm-table-cell"); $("td:eq(4)", row).html(amount); - $("td:eq(5)", row).html('' + format_unixtime(timestamp) + '').addClass('text-center'); + + if (#{settings.block_page.multi_algorithm.show_algo} == true) { + var algo = (data.length > 6 && data[6].indexOf('algo:') == 0 ? data[6].substring('algo:'.length) : ''); + $("td:eq(5)", row).html(algo); + offset = 1; + } + + $("td:eq(" + (5 + offset) + ")", row).html('' + format_unixtime(timestamp) + '').addClass('text-center'); }, fnDrawCallback: function(settings) { fixDataTableColumns(); @@ -169,5 +179,7 @@ block content th.text-center.d-none.d-sm-table-cell #{settings.locale.tx_recipients} th.text-center #{settings.locale.mkt_amount} span.small.fw-normal (#{settings.coin.symbol}) + if settings.block_page.multi_algorithm.show_algo == true + th.text-center="Algorithm" th.text-center #{settings.locale.timestamp} tbody.text-center \ No newline at end of file