poa-network-monitor/network-test/mining-reward-check.js

115 lines
4.7 KiB
JavaScript

// check if payout script works properly for all nodes (check mining address balance)
const {
config,
getNetworkName,
getWeb3,
BN,
testHelper,
} = require('./test-helper.js');
let web3 = getWeb3();
const {SqlDao} = require('../common/dao.js');
const sqlDao = new SqlDao(getNetworkName());
sqlDao.createRewardTable();
/*
* Gets blocks from the latest round and checks reward
*/
async function checkMiningReward() {
console.log("checkMiningReward");
const validatorsArr = await testHelper.getValidators(web3);
let blocksToTest = await getBlocksFromLatestRound(validatorsArr.length);
for (let i = 0; i < blocksToTest.length; i++) {
let result = await checkBlocksRewards(blocksToTest[i]);
console.log("passed: " + result.passed + ", rewardDetails: " + JSON.stringify(result.rewardDetails) +
", transactions: " + JSON.stringify(result.transactions));
sqlDao.addToRewardTable([new Date(Date.now()).toISOString(), (result.passed) ? 1 : 0, result.error,
JSON.stringify(result.rewardDetails), JSON.stringify(result.transactions)]);
}
sqlDao.closeDb();
}
//todo check error for all tests
checkMiningReward();
/**
* Checks if miner got right reward for block creation and adding txs to the block
*
* @param block (or objects with fields number and miner)
* @returns {Promise.<{passed: boolean, error: string, rewardDetails: Array}>}
*/
async function checkBlocksRewards(block) {
// todo: save each validator's rewards
let result = {passed: true, error: "", rewardDetails: {}, transactions: []};
console.log("number: " + block.number + ", miner: " + block.miner);
let actualBalanceIncrease = new BN(await web3.eth.getBalance(block.miner, block.number)).sub(new BN(await web3.eth.getBalance(block.miner, block.number - 1)));
let expectedBalanceIncrease = new BN(config.miningReward);
console.log("got reward: " + actualBalanceIncrease);
console.log("config.miningReward: " + config.miningReward);
//reward will be different if there are txs
for (let j = 0; j < block.transactions.length; j++) {
let details = {hash: "", price: "", value: "", to: "", from: "", blockNumber: ""};
let tx = await web3.eth.getTransaction(block.transactions[j]);
let gasPrice = new BN(tx.gasPrice);
let receipt = await web3.eth.getTransactionReceipt(block.transactions[j]);
let transactionPrice = new BN(receipt.gasUsed).mul(gasPrice);
details.hash = receipt.transactionHash;
details.from = tx.from;
details.to = tx.to;
details.gasPrice = gasPrice.toString();
details.gasUsed = receipt.gasUsed;
console.log("receipt.from: " + tx.from);
console.log("receipt.to: " + tx.to);
details.price = transactionPrice.toString();
details.value = tx.value;
details.blockNumber = block.number;
if (!(tx.from === block.miner)) {
expectedBalanceIncrease = expectedBalanceIncrease.add(transactionPrice);
}
else if (tx.from === block.miner) {
expectedBalanceIncrease = expectedBalanceIncrease.sub(new BN(tx.value));
}
else if (tx.to === block.miner) {
expectedBalanceIncrease = expectedBalanceIncrease.add(new BN(tx.value));
}
console.log("transaction details: " + JSON.stringify(details));
result.transactions.push(details);
console.log("expectedBalanceIncrease: " + expectedBalanceIncrease);
}
result.rewardDetails = {
validator: block.miner,
block: block.number,
gasUsed: block.gasUsed,
basicReward: config.miningReward,
expectedReward: expectedBalanceIncrease.toString(),
actualReward: actualBalanceIncrease.toString(),
txsNumber: block.transactions.length,
};
let isRewardRight = actualBalanceIncrease.eq(expectedBalanceIncrease);
if (!isRewardRight) {
result.passed = false;
result.error = "Wrong reward, \n" + "validator: " + block.miner + "\nexpected: " + expectedBalanceIncrease + "\nactual: " + actualBalanceIncrease +
"\nblock: " + block.number + "; \n\n";
}
return result;
}
/**
* Returns the array of latest blocks. Array length will be equal to the number of validators to fit the round.
*
* @param numberOfValidators
* @returns {Array}
*/
async function getBlocksFromLatestRound(numberOfValidators) {
const lastBlock = await web3.eth.getBlock('latest');
const firstNum = lastBlock.number - numberOfValidators + 1;
let blocks = [];
for (let i = 0; i < numberOfValidators; i++) {
blocks[i] = await web3.eth.getBlock(firstNum + i);
}
console.log("getBlocksFromLatestRound blocks.length: " + blocks.length);
return blocks;
}