From 616275b087787de3e42dc3c60073d9f337ff9b01 Mon Sep 17 00:00:00 2001 From: zzzckck <152148891+zzzckck@users.noreply.github.com> Date: Mon, 5 Aug 2024 14:14:32 +0800 Subject: [PATCH 1/3] utils: merge several jsutils into one --- cmd/jsutils/getchainstatus.js | 112 +++++++++++++++++++++++++++++ cmd/jsutils/gettxcount.js | 41 ----------- cmd/jsutils/getvalidatorversion.js | 38 ---------- 3 files changed, 112 insertions(+), 79 deletions(-) create mode 100644 cmd/jsutils/getchainstatus.js delete mode 100644 cmd/jsutils/gettxcount.js delete mode 100644 cmd/jsutils/getvalidatorversion.js diff --git a/cmd/jsutils/getchainstatus.js b/cmd/jsutils/getchainstatus.js new file mode 100644 index 0000000000..3239a4752d --- /dev/null +++ b/cmd/jsutils/getchainstatus.js @@ -0,0 +1,112 @@ +import { ethers } from "ethers"; +import program from "commander"; + +program.option("--rpc ", "Rpc"); +program.option("--startNum ", "start num") +program.option("--endNum ", "end num") +program.option("--miner ", "miner", "") +program.option("--num ", "validator num", 21) + +program.parse(process.argv); + +const provider = new ethers.JsonRpcProvider(program.rpc) + +function printUsage() { + console.log("Usage:"); + console.log(" node getchainstatus.js --help"); + console.log(" node getchainstatus.js [subcommand] [options]"); + console.log("\nSubcommands:"); + console.log(" GetTxCount: find the block with max tx size of a range"); + console.log(" GetValidatorVersion: dump validators' binary version, based on Header.Extra"); + console.log("\nOptions:"); + console.log(" --rpc specify the url of RPC endpoint"); + console.log(" --startNum the start block number, for command GetTxCount"); + console.log(" --endNum the end block number, for command GetTxCount"); + console.log(" --miner the miner address, for command GetTxCount"); + console.log(" --num the number of blocks to be checked, for command GetValidatorVersion"); + console.log("\nExample:"); + console.log(" node getchainstatus.js GetTxCount --rpc https://bsc-mainnet.nodereal.io/v1/454e504917db4f82b756bd0cf6317dce --startNum 40000001 --endNum 40000005") + console.log(" node getchainstatus.js GetValidatorVersion --rpc https://bsc-mainnet.nodereal.io/v1/454e504917db4f82b756bd0cf6317dce --num 21") +} + +// 1.cmd: "GetTxCount", usage: +// node getchainstatus.js GetTxCount --rpc https://bsc-mainnet.nodereal.io/v1/454e504917db4f82b756bd0cf6317dce --startNum 40000001 --endNum 40000005 +// --miner: +// specified: find the max txCounter from the specified validator +// not specified: find the max txCounter from all validators +async function getTxCount() { + let txCount = 0; + let num = 0; + console.log("Find the max txs count between", program.startNum, "and", program.endNum); + for (let i = program.startNum; i < program.endNum; i++) { + if (program.miner !== "") { + let blockData = await provider.getBlock(Number(i)) + if (program.miner !== blockData.miner) { + continue + } + } + let x = await provider.send("eth_getBlockTransactionCountByNumber", [ + ethers.toQuantity(i)]); + let a = ethers.toNumber(x) + if (a > txCount) { + num = i; + txCount = a; + } + } + console.log("BlockNum = ", num, "TxCount =", txCount); +} + +// 2.cmd: "GetValidatorVersion", usage: +// node getchainstatus.js GetValidatorVersion \ +// --rpc https://bsc-mainnet.nodereal.io/v1/454e504917db4f82b756bd0cf6317dce \ +// --num(optional): defualt 21, the number of blocks that will be checked +async function getValidatorVersion() { + const blockNum = await provider.getBlockNumber(); + console.log(blockNum); + for (let i = 0; i < program.num; i++) { + let blockData = await provider.getBlock(blockNum - i); + // 1.get Geth client version + let major = ethers.toNumber(ethers.dataSlice(blockData.extraData, 2, 3)) + let minor = ethers.toNumber(ethers.dataSlice(blockData.extraData, 3, 4)) + let patch = ethers.toNumber(ethers.dataSlice(blockData.extraData, 4, 5)) + + // 2.get minimum txGasPrice based on the last non-zero-gasprice transaction + let lastGasPrice = 0 + for (let txIndex = blockData.transactions.length - 1; txIndex >= 0; txIndex--) { + let txHash = blockData.transactions[txIndex] + let txData = await provider.getTransaction(txHash); + if (txData.gasPrice == 0) { + continue + } + lastGasPrice = txData.gasPrice + break + } + console.log(blockData.miner, "version =", major + "." + minor + "." + patch, " MinGasPrice = " + lastGasPrice) + } +}; + +const main = async () => { + if (process.argv.length <= 2) { + console.error('invalid process.argv.length', process.argv.length); + printUsage() + return + } + const cmd = process.argv[2] + if (cmd === "--help") { + printUsage() + return + } + if (cmd === "GetTxCount") { + await getTxCount() + } else if (cmd === "GetValidatorVersion") { + await getValidatorVersion() + } else { + console.log("unsupported cmd", cmd); + } +} + +main().then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); \ No newline at end of file diff --git a/cmd/jsutils/gettxcount.js b/cmd/jsutils/gettxcount.js deleted file mode 100644 index 8bc7f2bdd9..0000000000 --- a/cmd/jsutils/gettxcount.js +++ /dev/null @@ -1,41 +0,0 @@ -import { ethers } from "ethers"; -import program from "commander"; - -program.option("--rpc ", "Rpc"); -program.option("--startNum ", "start num") -program.option("--endNum ", "end num") -// --miner: -// specified: find the max txCounter from the specified validator -// not specified: find the max txCounter from all validators -program.option("--miner ", "miner", "") -program.parse(process.argv); - -const provider = new ethers.JsonRpcProvider(program.rpc) - -const main = async () => { - let txCount = 0; - let num = 0; - console.log("Find the max txs count between", program.startNum, "and", program.endNum); - for (let i = program.startNum; i < program.endNum; i++) { - if (program.miner !== "") { - let blockData = await provider.getBlock(Number(i)) - if (program.miner !== blockData.miner) { - continue - } - } - let x = await provider.send("eth_getBlockTransactionCountByNumber", [ - ethers.toQuantity(i)]); - let a = ethers.toNumber(x) - if (a > txCount) { - num = i; - txCount = a; - } - } - console.log("BlockNum = ", num, "TxCount =", txCount); -}; - -main().then(() => process.exit(0)) - .catch((error) => { - console.error(error); - process.exit(1); - }); \ No newline at end of file diff --git a/cmd/jsutils/getvalidatorversion.js b/cmd/jsutils/getvalidatorversion.js deleted file mode 100644 index 495b913f43..0000000000 --- a/cmd/jsutils/getvalidatorversion.js +++ /dev/null @@ -1,38 +0,0 @@ -import { ethers } from "ethers"; -import program from "commander"; - -program.option("--Rpc ", "Rpc"); -program.option("--Num ", "validator num", 21) -program.parse(process.argv); - -const provider = new ethers.JsonRpcProvider(program.Rpc); - -const main = async () => { - const blockNum = await provider.getBlockNumber(); - console.log(blockNum); - for (let i = 0; i < program.Num; i++) { - let blockData = await provider.getBlock(blockNum - i); - // 1.get Geth client version - let major = ethers.toNumber(ethers.dataSlice(blockData.extraData, 2, 3)) - let minor = ethers.toNumber(ethers.dataSlice(blockData.extraData, 3, 4)) - let patch = ethers.toNumber(ethers.dataSlice(blockData.extraData, 4, 5)) - - // 2.get minimum txGasPrice based on the last non-zero-gasprice transaction - let lastGasPrice = 0 - for (let txIndex = blockData.transactions.length - 1; txIndex >= 0; txIndex--) { - let txHash = blockData.transactions[txIndex] - let txData = await provider.getTransaction(txHash); - if (txData.gasPrice == 0) { - continue - } - lastGasPrice = txData.gasPrice - break - } - console.log(blockData.miner, "version =", major + "." + minor + "." + patch, " MinGasPrice = " + lastGasPrice) - } -}; -main().then(() => process.exit(0)) - .catch((error) => { - console.error(error); - process.exit(1); - }); \ No newline at end of file From ce25a3712fd7401bd2a2e2da9dd6edf9d89123bf Mon Sep 17 00:00:00 2001 From: zzzckck <152148891+zzzckck@users.noreply.github.com> Date: Mon, 5 Aug 2024 15:46:18 +0800 Subject: [PATCH 2/3] utils: add GetTopAddr to analyse large traffic --- cmd/jsutils/getchainstatus.js | 77 ++++++++++++++++++++++++++++------- 1 file changed, 63 insertions(+), 14 deletions(-) diff --git a/cmd/jsutils/getchainstatus.js b/cmd/jsutils/getchainstatus.js index 3239a4752d..5d3d44b905 100644 --- a/cmd/jsutils/getchainstatus.js +++ b/cmd/jsutils/getchainstatus.js @@ -1,11 +1,16 @@ import { ethers } from "ethers"; import program from "commander"; +// Global Options: program.option("--rpc ", "Rpc"); +// GetTxCount Options: program.option("--startNum ", "start num") program.option("--endNum ", "end num") program.option("--miner ", "miner", "") +// GetVersion Options: program.option("--num ", "validator num", 21) +// GetTopAddr Options: +program.option("--topNum ", "top num of address to be displayed", 20) program.parse(process.argv); @@ -17,23 +22,27 @@ function printUsage() { console.log(" node getchainstatus.js [subcommand] [options]"); console.log("\nSubcommands:"); console.log(" GetTxCount: find the block with max tx size of a range"); - console.log(" GetValidatorVersion: dump validators' binary version, based on Header.Extra"); + console.log(" GetVersion: dump validators' binary version, based on Header.Extra"); + console.log(" GetTopAddr: get hottest $topNum target address within a block range"); console.log("\nOptions:"); console.log(" --rpc specify the url of RPC endpoint"); console.log(" --startNum the start block number, for command GetTxCount"); console.log(" --endNum the end block number, for command GetTxCount"); console.log(" --miner the miner address, for command GetTxCount"); - console.log(" --num the number of blocks to be checked, for command GetValidatorVersion"); + console.log(" --num the number of blocks to be checked, for command GetVersion"); + console.log(" --topNum the topNum of blocks to be checked, for command GetVersion"); console.log("\nExample:"); - console.log(" node getchainstatus.js GetTxCount --rpc https://bsc-mainnet.nodereal.io/v1/454e504917db4f82b756bd0cf6317dce --startNum 40000001 --endNum 40000005") - console.log(" node getchainstatus.js GetValidatorVersion --rpc https://bsc-mainnet.nodereal.io/v1/454e504917db4f82b756bd0cf6317dce --num 21") + // mainnet https://bsc-mainnet.nodereal.io/v1/454e504917db4f82b756bd0cf6317dce + console.log(" node getchainstatus.js GetTxCount --rpc https://bsc-testnet-dataseed.bnbchain.org --startNum 40000001 --endNum 40000005") + console.log(" node getchainstatus.js GetVersion --rpc https://bsc-testnet-dataseed.bnbchain.org --num 21") + console.log(" node getchainstatus.js GetTopAddr --rpc https://bsc-testnet-dataseed.bnbchain.org --startNum 40000001 --endNum 40000010 --topNum 10") } // 1.cmd: "GetTxCount", usage: -// node getchainstatus.js GetTxCount --rpc https://bsc-mainnet.nodereal.io/v1/454e504917db4f82b756bd0cf6317dce --startNum 40000001 --endNum 40000005 -// --miner: -// specified: find the max txCounter from the specified validator -// not specified: find the max txCounter from all validators +// node getchainstatus.js GetTxCount --rpc https://bsc-testnet-dataseed.bnbchain.org \ +// --startNum 40000001 --endNum 40000005 \ +// --miner(optional): specified: find the max txCounter from the specified validator, +// not specified: find the max txCounter from all validators async function getTxCount() { let txCount = 0; let num = 0; @@ -56,11 +65,11 @@ async function getTxCount() { console.log("BlockNum = ", num, "TxCount =", txCount); } -// 2.cmd: "GetValidatorVersion", usage: -// node getchainstatus.js GetValidatorVersion \ -// --rpc https://bsc-mainnet.nodereal.io/v1/454e504917db4f82b756bd0cf6317dce \ +// 2.cmd: "GetVersion", usage: +// node getchainstatus.js GetVersion \ +// --rpc https://bsc-testnet-dataseed.bnbchain.org \ // --num(optional): defualt 21, the number of blocks that will be checked -async function getValidatorVersion() { +async function getBinaryVersion() { const blockNum = await provider.getBlockNumber(); console.log(blockNum); for (let i = 0; i < program.num; i++) { @@ -85,6 +94,43 @@ async function getValidatorVersion() { } }; +// 3.cmd: "GetTopAddr", usage: +// node getchainstatus.js GetTopAddr \ +// --rpc https://bsc-testnet-dataseed.bnbchain.org \ +// --startNum 40000001 --endNum 40000005 \ +// --topNum(optional): the top num of address to be displayed, default 20 +function getTopKElements(map, k) { + let entries = Array.from(map.entries()); + entries.sort((a, b) => b[1] - a[1]); + return entries.slice(0, k); +} + +async function getTopAddr() { + let countMap = new Map(); + console.log("Find the top target address, between", program.startNum, "and", program.endNum); + for (let i = program.startNum; i < program.endNum; i++) { + let blockData = await provider.getBlock(Number(i), true) + for (let txIndex = blockData.transactions.length - 1; txIndex >= 0; txIndex--) { + let txData = await blockData.getTransaction(txIndex) + if (txData.to == null) { + console.log("Contract creation,txHash:", txData.hash) + continue + } + let toAddr = txData.to; + if (countMap.has(toAddr)) { + countMap.set(toAddr, countMap.get(toAddr) + 1); + } else { + countMap.set(toAddr, 1); + } + } + console.log("progress:", (program.endNum-i), "blocks left") + } + let tops = getTopKElements(countMap, program.topNum) + tops.forEach((value, key) => { + console.log(`${key}, Value: ${value}`); + }); +}; + const main = async () => { if (process.argv.length <= 2) { console.error('invalid process.argv.length', process.argv.length); @@ -98,10 +144,13 @@ const main = async () => { } if (cmd === "GetTxCount") { await getTxCount() - } else if (cmd === "GetValidatorVersion") { - await getValidatorVersion() + } else if (cmd === "GetVersion") { + await getBinaryVersion() + } else if (cmd === "GetTopAddr") { + await getTopAddr() } else { console.log("unsupported cmd", cmd); + printUsage() } } From 8a51156526b2b747fe9d070829fbba33ea759b02 Mon Sep 17 00:00:00 2001 From: zzzckck <152148891+zzzckck@users.noreply.github.com> Date: Mon, 5 Aug 2024 16:30:54 +0800 Subject: [PATCH 3/3] utils: print % for GetTopAddr --- cmd/jsutils/getchainstatus.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/cmd/jsutils/getchainstatus.js b/cmd/jsutils/getchainstatus.js index 5d3d44b905..db5e25cf48 100644 --- a/cmd/jsutils/getchainstatus.js +++ b/cmd/jsutils/getchainstatus.js @@ -107,9 +107,11 @@ function getTopKElements(map, k) { async function getTopAddr() { let countMap = new Map(); + let totalTxs = 0 console.log("Find the top target address, between", program.startNum, "and", program.endNum); - for (let i = program.startNum; i < program.endNum; i++) { + for (let i = program.startNum; i <= program.endNum; i++) { let blockData = await provider.getBlock(Number(i), true) + totalTxs += blockData.transactions.length for (let txIndex = blockData.transactions.length - 1; txIndex >= 0; txIndex--) { let txData = await blockData.getTransaction(txIndex) if (txData.to == null) { @@ -123,11 +125,12 @@ async function getTopAddr() { countMap.set(toAddr, 1); } } - console.log("progress:", (program.endNum-i), "blocks left") + console.log("progress:", (program.endNum-i), "blocks left", "totalTxs", totalTxs) } let tops = getTopKElements(countMap, program.topNum) tops.forEach((value, key) => { - console.log(`${key}, Value: ${value}`); + // value: [ '0x40661F989826CC641Ce1601526Bb16a4221412c8', 71 ] + console.log(key+":", value[0], " ", value[1], " ", ((value[1]*100)/totalTxs).toFixed(2)+"%"); }); };