Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jsutils: add tool GetKeyParameters #2749

Merged
merged 2 commits into from
Nov 7, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 127 additions & 39 deletions cmd/jsutils/getchainstatus.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ function printUsage() {
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(" GetVersion: dump validators' binary version, based on Header.Extra");
console.log(" GetMaxTxCountInBlockRange: find the block with max tx size of a range");
console.log(" GetBinaryVersion: dump validators' binary version, based on Header.Extra");
console.log(" GetTopAddr: get hottest $topNum target address of a block range");
console.log(" GetSlashCount: get slash state at a specific block height");
console.log(" GetPerformanceData: analyze the performance data of a block range");
console.log(" GetBlobTxs: get BlobTxs of a block range");
console.log(" GetFaucetStatus: get faucet status of BSC testnet");
console.log(" GetKeyParameters: dump some key governance parameter");
console.log("\nOptions:");
console.log(" --rpc specify the url of RPC endpoint");
console.log(" --startNum the start block number");
Expand All @@ -32,33 +33,54 @@ function printUsage() {
console.log(" --blockNum the block number to be checked");
console.log("\nExample:");
// 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 GetMaxTxCountInBlockRange --rpc https://bsc-testnet-dataseed.bnbchain.org --startNum 40000001 --endNum 40000005")
console.log(" node getchainstatus.js GetBinaryVersion --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")
console.log(" node getchainstatus.js GetSlashCount --rpc https://bsc-testnet-dataseed.bnbchain.org --blockNum 40000001") // latest block if `--blockNum` is not specified
console.log(" node getchainstatus.js GetSlashCount --rpc https://bsc-testnet-dataseed.bnbchain.org --blockNum 40000001") // default: latest block
console.log(" node getchainstatus.js GetPerformanceData --rpc https://bsc-testnet-dataseed.bnbchain.org --startNum 40000001 --endNum 40000010")
console.log(" node getchainstatus.js GetBlobTxs --rpc https://bsc-testnet-dataseed.bnbchain.org --startNum 40000001 --endNum 40000010")
console.log(" node getchainstatus.js GetFaucetStatus --rpc https://bsc-testnet-dataseed.bnbchain.org --startNum 40000001 --endNum 40000010")
console.log(" node getchainstatus.js GetKeyParameters --rpc https://bsc-testnet-dataseed.bnbchain.org") // default: latest block
}

program.usage = printUsage;
program.parse(process.argv);

const provider = new ethers.JsonRpcProvider(program.rpc)

const addrValidatorSet = '0x0000000000000000000000000000000000001000';
const addrSlash = '0x0000000000000000000000000000000000001001';
const addrStakeHub = '0x0000000000000000000000000000000000002002';

const validatorSetAbi = [
"function getLivingValidators() external view returns (address[], bytes[])",
"function numOfCabinets() external view returns (uint256)",
"function maxNumOfCandidates() external view returns (uint256)",
"function maxNumOfWorkingCandidates() external view returns (uint256)",
"function maxNumOfMaintaining() external view returns (uint256)", // default 3
"function turnLength() external view returns (uint256)",
"function systemRewardAntiMEVRatio() external view returns (uint256)",
"function maintainSlashScale() external view returns (uint256)", // default 2, valid: 1->9
"function burnRatio() external view returns (uint256)", // default: 10%
"function systemRewardBaseRatio() external view returns (uint256)" // default: 1/16
]
const slashAbi = [
"function getSlashIndicator(address validatorAddr) external view returns (uint256, uint256)"
]
const validatorSetAbi = [
"function getLivingValidators() external view returns (address[], bytes[])"
]

// https://github.com/bnb-chain/bsc-genesis-contract/blob/master/contracts/StakeHub.sol
const stakeHubAbi = [
"function getValidatorElectionInfo(uint256 offset, uint256 limit) external view returns (address[], uint256[], bytes[], uint256)",
"function getValidatorDescription(address validatorAddr) external view returns (tuple(string, string, string, string))",
"function consensusToOperator(address consensusAddr) public view returns (address)"
"function consensusToOperator(address consensusAddr) public view returns (address)",
"function minSelfDelegationBNB() public view returns (uint256)", // default 2000, valid: 1000 -> 100,000
"function maxElectedValidators() public view returns (uint256)", // valid: 1 -> 500
"function unbondPeriod() public view returns (uint256)", // default 7days, valid: 3days ->30days
"function downtimeSlashAmount() public view returns (uint256)", // default 10BNB, valid: 5 -> felonySlashAmount
"function felonySlashAmount() public view returns (uint256)", // default 200BNB, valid: > max(100, downtimeSlashAmount)
"function downtimeJailTime() public view returns (uint256)", // default 2days,
"function felonyJailTime() public view returns (uint256)" // default 30days,
]
const addrValidatorSet = '0x0000000000000000000000000000000000001000';
const addrSlash = '0x0000000000000000000000000000000000001001';
const addrStakeHub = '0x0000000000000000000000000000000000002002';

const validatorSet = new ethers.Contract(addrValidatorSet, validatorSetAbi, provider);
const slashIndicator = new ethers.Contract(addrSlash, slashAbi, provider)
Expand Down Expand Up @@ -120,15 +142,31 @@ const validatorMap = new Map([
["0x1a3d9D7A717D64e6088aC937d5aAcDD3E20ca963","Elbrus"],
["0x40D3256EB0BaBE89f0ea54EDAa398513136612f5","Bloxroute"],
["0xF9a1Db0d6f22Bd78ffAECCbc8F47c83Df9FBdbCf","Test"],
["0xB4cd0dCF71381b452A92A359BbE7146e8825Ce46","BSCLista"]
["0xB4cd0dCF71381b452A92A359BbE7146e8825Ce46","BSCLista"],
["0xD7b26968D8AD24f433d422b18A11a6580654Af13","TNkgnL4"],
["0xFDA4C7E5C6005511236E24f3d5eBFd65Ffa10AED","MyHave"],
["0x73f86c0628e04A69dcb61944F0df5DE115bA3FD8","InfStones"],
["0xcAc5E4158fAb2eB95aA5D9c8DdfC9DF7208fDc58","My5eVal"],
["0x96f6a2A267C726973e40cCCBB956f1716Bac7dc0","ForDc0"],
["0x15a13e315CbfB9398A26D77a299963BF034c28F8","Blxr"],
["0x1d622CAcd06c0eafd0a8a4C66754C96Db50cE14C","Val9B"],
["0xd6BD505f4CFc19203875A92B897B07DE13d118ce","Panipuri"],
["0x9532223eAa6Eb6939A00C0A39A054d93b5cCf4Af","TrustT"],
["0xB19b6057245002442123371494372719d2Beb83D","Vtwval"],
["0x5530Bac059E50821E7146D951e56FC7500bda007","LedgrTrus"],
["0xEe22F03961b407bCBae66499a029Be4cA0AF4ab4","AB4"],
["0x1AE5f5C3Cb452E042b0B7b9DC60596C9CD84BaF6","Jake"],
["0xfA4d592F9B152f7a10B5DE9bE24C27a74BCE431A","MyTWFMM"]
]);

// 1.cmd: "GetTxCount", usage:
// node getchainstatus.js GetTxCount --rpc https://bsc-testnet-dataseed.bnbchain.org \


// 1.cmd: "GetMaxTxCountInBlockRange", usage:
// node getchainstatus.js GetMaxTxCountInBlockRange --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() {
async function getMaxTxCountInBlockRange() {
let txCount = 0;
let num = 0;
console.log("Find the max txs count between", program.startNum, "and", program.endNum);
Expand All @@ -150,8 +188,8 @@ async function getTxCount() {
console.log("BlockNum = ", num, "TxCount =", txCount);
}

// 2.cmd: "GetVersion", usage:
// node getchainstatus.js GetVersion \
// 2.cmd: "GetBinaryVersion", usage:
// node getchainstatus.js GetBinaryVersion \
// --rpc https://bsc-testnet-dataseed.bnbchain.org \
// --num(optional): defualt 21, the number of blocks that will be checked
async function getBinaryVersion() {
Expand Down Expand Up @@ -223,6 +261,17 @@ async function getTopAddr() {
// node getchainstatus.js GetSlashCount \
// --rpc https://bsc-testnet-dataseed.bnbchain.org \
// --blockNum(optional): the block num which is based for the slash state, default: latest block
async function getValidatorMoniker(consensusAddr, blockNum) {
if (validatorMap.has(consensusAddr)) {
return validatorMap.get(consensusAddr)
}
let opAddr = await stakeHub.consensusToOperator(consensusAddr, {blockTag:blockNum})
let desc = await stakeHub.getValidatorDescription(opAddr, {blockTag:blockNum})
let moniker = desc[0]
console.log(consensusAddr, moniker)
return moniker
}

async function getSlashCount() {
let blockNum = ethers.getNumber(program.blockNum)
if (blockNum === 0) {
Expand All @@ -234,28 +283,20 @@ async function getSlashCount() {
let totalSlash = 0
for (let i = 0; i < data[0].length; i++) {
let addr = data[0][i];
var val
if (!validatorMap.has(addr)) {
let opAddr = await stakeHub.consensusToOperator(addr, {blockTag:blockNum})
let value = await stakeHub.getValidatorDescription(opAddr, {blockTag:blockNum})
val = value[0]
console.log(addr, val)
} else {
val = validatorMap.get(addr)
}
var moniker = await getValidatorMoniker(addr, blockNum)
let info = await slashIndicator.getSlashIndicator(addr, {blockTag:blockNum})
let count = ethers.toNumber(info[1])
totalSlash += count
console.log("Slash:", count, addr, val)
console.log("Slash:", count, addr, moniker)
}
console.log("Total slash count", totalSlash)
};

// 5.cmd: "GetPerformanceData", usage:
// node getchainstatus.js GetPerformanceData \
// 5.cmd: "getPerformanceData", usage:
// node getchainstatus.js getPerformanceData \
// --rpc https://bsc-testnet-dataseed.bnbchain.org \
// --startNum 40000001 --endNum 40000005
async function GetPerformanceData() {
async function getPerformanceData() {
let txCountTotal = 0;
let gasUsedTotal = 0;
let inturnBlocks = 0;
Expand Down Expand Up @@ -323,7 +364,7 @@ async function GetPerformanceData() {
// --startNum 40000001 --endNum 40000005
// depends on ethjs v6.11.0+ for 4844, https://github.com/ethers-io/ethers.js/releases/tag/v6.11.0
// BSC testnet enabled 4844 on block: 39539137
async function GetBlobTxs() {
async function getBlobTxs() {
var startBlock = parseInt(program.startNum)
var endBlock = parseInt(program.endNum)
if (isNaN(endBlock) || isNaN(startBlock) || startBlock == 0) {
Expand Down Expand Up @@ -359,7 +400,7 @@ async function GetBlobTxs() {
// node getchainstatus.js GetFaucetStatus \
// --rpc https://bsc-testnet-dataseed.bnbchain.org \
// --startNum 40000001 --endNum 40000005
async function GetFaucetStatus() {
async function getFaucetStatus() {
var startBlock = parseInt(program.startNum)
var endBlock = parseInt(program.endNum)
if (isNaN(endBlock) || isNaN(startBlock) || startBlock == 0) {
Expand Down Expand Up @@ -390,6 +431,51 @@ async function GetFaucetStatus() {
console.log("successful faucet request: ",numFaucetRequest);
};


// 8.cmd: "GetKeyParameters", usage:
// node getchainstatus.js GetKeyParameters \
// --rpc https://bsc-testnet-dataseed.bnbchain.org \
// --blockNum(optional): the block num which is based for the slash state, default: latest block
async function getKeyParameters() {
let blockNum = ethers.getNumber(program.blockNum)
if (blockNum === 0) {
blockNum = await provider.getBlockNumber()
}
let block = await provider.getBlock(blockNum)
console.log("At block", blockNum, "time", block.date)

// part 1: validatorset
let numOfCabinets = await validatorSet.numOfCabinets({blockTag:blockNum})
if (numOfCabinets == 0) { numOfCabinets = 21 }
// let maxNumOfCandidates = await validatorSet.maxNumOfCandidates({blockTag:blockNum}) // deprecated
// let turnLength = await validatorSet.turnLength({blockTag:blockNum})
let maxNumOfWorkingCandidates = await validatorSet.maxNumOfWorkingCandidates({blockTag:blockNum})
let maintainSlashScale = await validatorSet.maintainSlashScale({blockTag:blockNum})
console.log("numOfCabinets", Number(numOfCabinets), "maxNumOfWorkingCandidates", Number(maxNumOfWorkingCandidates),
"maintainSlashScale", maintainSlashScale)

// part 2: staking
// let minSelfDelegationBNB = await stakeHub.minSelfDelegationBNB({blockTag:blockNum})/BigInt(10**18)
let maxElectedValidators = await stakeHub.maxElectedValidators({blockTag:blockNum})
let validatorElectionInfo = await stakeHub.getValidatorElectionInfo(0,0,{blockTag:blockNum})
let consensusAddrs = validatorElectionInfo[0]
let votingPowers = validatorElectionInfo[1]
let voteAddrs = validatorElectionInfo[2]
let totalLength = validatorElectionInfo[3]
console.log("maxElectedValidators", Number(maxElectedValidators), "Registered", Number(totalLength))
let validatorTable = []
for (let i = 0; i < totalLength; i++) {
validatorTable.push({
addr: consensusAddrs[i],
votingPower: Number(votingPowers[i]/BigInt(10**18)),
voteAddr: voteAddrs[i],
moniker: await getValidatorMoniker(consensusAddrs[i], blockNum)
})
}
validatorTable.sort((a, b) => b.votingPower - a.votingPower);
console.table(validatorTable)
};

const main = async () => {
if (process.argv.length <= 2) {
console.error('invalid process.argv.length', process.argv.length);
Expand All @@ -401,20 +487,22 @@ const main = async () => {
printUsage()
return
}
if (cmd === "GetTxCount") {
await getTxCount()
} else if (cmd === "GetVersion") {
if (cmd === "GetMaxTxCountInBlockRange") {
await getMaxTxCountInBlockRange()
} else if (cmd === "GetBinaryVersion") {
await getBinaryVersion()
} else if (cmd === "GetTopAddr") {
await getTopAddr()
} else if (cmd === "GetSlashCount") {
await getSlashCount()
} else if (cmd === "GetPerformanceData") {
await GetPerformanceData()
await getPerformanceData()
} else if (cmd === "GetBlobTxs") {
await GetBlobTxs()
await getBlobTxs()
} else if (cmd === "GetFaucetStatus") {
await GetFaucetStatus()
await getFaucetStatus()
} else if (cmd === "GetKeyParameters") {
await getKeyParameters()
} else {
console.log("unsupported cmd", cmd);
printUsage()
Expand Down
Loading