Expose merge-mining block classifications
Some checks failed
CodeQL / Analyze (javascript) (push) Failing after 41s
Some checks failed
CodeQL / Analyze (javascript) (push) Failing after 41s
This commit is contained in:
85
lib/api.js
85
lib/api.js
@@ -79,6 +79,9 @@ function handleServerRequest (request, response) {
|
||||
case '/get_blocks':
|
||||
handleGetBlocks(urlParts, response);
|
||||
break;
|
||||
case '/get_mm_blocks':
|
||||
handleGetMergeMiningBlocks(urlParts, response);
|
||||
break;
|
||||
|
||||
// Get market prices
|
||||
case '/get_market':
|
||||
@@ -1034,6 +1037,88 @@ function handleGetBlocks (urlParts, response) {
|
||||
});
|
||||
}
|
||||
|
||||
function parsePoolBlockEntry (serialized, score, source) {
|
||||
let block = serialized.split(':');
|
||||
let rewardType = block[0];
|
||||
let base = {
|
||||
source: source,
|
||||
height: parseInt(score),
|
||||
rewardType: rewardType,
|
||||
miner: rewardType === 'solo' || rewardType === 'prop'
|
||||
? `${block[1].substring(0, 7)}...${block[1].substring(block[1].length - 7)}`
|
||||
: block[1],
|
||||
hash: block[2],
|
||||
timestamp: parseInt(block[3]),
|
||||
difficulty: parseInt(block[4]),
|
||||
shares: parseInt(block[5]),
|
||||
orphaned: false,
|
||||
reward: null,
|
||||
mmClassification: 'plain',
|
||||
auxAccepted: false,
|
||||
parentAccepted: false
|
||||
};
|
||||
|
||||
if (source === 'candidate') {
|
||||
base.score = block[6] ? parseFloat(block[6]) : parseInt(block[5]);
|
||||
base.mmClassification = block[7] || 'plain';
|
||||
base.auxAccepted = block[8] === '1';
|
||||
base.parentAccepted = block[9] === '1';
|
||||
return base;
|
||||
}
|
||||
|
||||
base.orphaned = block[6] === '1';
|
||||
let hasReward = block.length >= 8 && /^\d+$/.test(block[7]);
|
||||
base.reward = hasReward ? block[7] : null;
|
||||
let mmIndex = hasReward ? 8 : 7;
|
||||
base.mmClassification = block[mmIndex] || 'plain';
|
||||
base.auxAccepted = block[mmIndex + 1] === '1';
|
||||
base.parentAccepted = block[mmIndex + 2] === '1';
|
||||
return base;
|
||||
}
|
||||
|
||||
function handleGetMergeMiningBlocks (urlParts, response) {
|
||||
let fromHeight = parseInt(urlParts.query.from_height || 0);
|
||||
let limit = parseInt(urlParts.query.limit || config.api.blocks || 100);
|
||||
if (isNaN(fromHeight) || fromHeight < 0) fromHeight = 0;
|
||||
if (isNaN(limit) || limit <= 0) limit = config.api.blocks || 100;
|
||||
|
||||
let redisCommands = [
|
||||
['zrevrangebyscore', `${config.coin}:blocks:candidates`, '+inf', fromHeight, 'WITHSCORES', 'LIMIT', 0, limit],
|
||||
['zrevrangebyscore', `${config.coin}:blocks:matured`, '+inf', fromHeight, 'WITHSCORES', 'LIMIT', 0, limit]
|
||||
];
|
||||
|
||||
redisClient.multi(redisCommands).exec(function (err, replies) {
|
||||
let data;
|
||||
if (err) {
|
||||
data = { error: 'Query failed' };
|
||||
} else {
|
||||
let items = [];
|
||||
let candidates = replies[0] || [];
|
||||
let matured = replies[1] || [];
|
||||
|
||||
for (let i = 0; i < candidates.length; i += 2) {
|
||||
items.push(parsePoolBlockEntry(candidates[i], candidates[i + 1], 'candidate'));
|
||||
}
|
||||
for (let i = 0; i < matured.length; i += 2) {
|
||||
items.push(parsePoolBlockEntry(matured[i], matured[i + 1], 'matured'));
|
||||
}
|
||||
|
||||
data = {
|
||||
items: items
|
||||
};
|
||||
}
|
||||
|
||||
let reply = JSON.stringify(data);
|
||||
response.writeHead("200", {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Cache-Control': 'no-cache',
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': Buffer.byteLength(reply, 'utf8')
|
||||
});
|
||||
response.end(reply);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get market exchange prices
|
||||
**/
|
||||
|
||||
@@ -53,7 +53,10 @@ function runInterval () {
|
||||
time: parts[3],
|
||||
difficulty: parts[4],
|
||||
shares: parts[5],
|
||||
score: parts.length >= 7 ? parts[6] : parts[5]
|
||||
score: parts.length >= 7 ? parts[6] : parts[5],
|
||||
mmClassification: parts.length >= 8 ? parts[7] : 'plain',
|
||||
auxAccepted: parts.length >= 9 ? parts[8] : 0,
|
||||
parentAccepted: parts.length >= 10 ? parts[9] : 0
|
||||
});
|
||||
}
|
||||
callback(null, blocks);
|
||||
@@ -159,7 +162,10 @@ function runInterval () {
|
||||
block.time,
|
||||
block.difficulty,
|
||||
block.shares,
|
||||
block.orphaned
|
||||
block.orphaned,
|
||||
block.mmClassification || 'plain',
|
||||
block.auxAccepted || 0,
|
||||
block.parentAccepted || 0
|
||||
].join(':')]);
|
||||
|
||||
if (block.workerScores && !slushMiningEnabled) {
|
||||
@@ -217,7 +223,10 @@ function runInterval () {
|
||||
block.difficulty,
|
||||
block.shares,
|
||||
block.orphaned,
|
||||
block.reward
|
||||
block.reward,
|
||||
block.mmClassification || 'plain',
|
||||
block.auxAccepted || 0,
|
||||
block.parentAccepted || 0
|
||||
].join(':')]);
|
||||
|
||||
let feePercent = (config.blockUnlocker.poolFee > 0 ? config.blockUnlocker.poolFee : 0) / 100;
|
||||
|
||||
21
lib/pool.js
21
lib/pool.js
@@ -881,6 +881,20 @@ function recordShareData (miner, job, shareDiff, blockCandidate, hashHex, shareT
|
||||
let candidateHash = blockMeta && blockMeta.hash ? blockMeta.hash : hashHex;
|
||||
let workerName = miner.workerName;
|
||||
let rewardType = miner.rewardType;
|
||||
let mmClassification = 'plain';
|
||||
let auxAccepted = 0;
|
||||
let parentAccepted = 0;
|
||||
|
||||
if (arguments.length >= 9 && arguments[8]) {
|
||||
let submitResult = arguments[8];
|
||||
auxAccepted = submitResult.aux_accepted ? 1 : 0;
|
||||
parentAccepted = submitResult.parent_accepted ? 1 : 0;
|
||||
if (auxAccepted && parentAccepted) {
|
||||
mmClassification = 'dual-mm';
|
||||
} else if (auxAccepted) {
|
||||
mmClassification = 'aux-mm';
|
||||
}
|
||||
}
|
||||
let updateScore;
|
||||
// Weighting older shares lower than newer ones to prevent pool hopping
|
||||
if (slushMiningEnabled) {
|
||||
@@ -991,7 +1005,10 @@ function recordShareData (miner, job, shareDiff, blockCandidate, hashHex, shareT
|
||||
Date.now() / 1000 | 0,
|
||||
blockTemplate.difficulty,
|
||||
totalShares,
|
||||
totalScore
|
||||
totalScore,
|
||||
mmClassification,
|
||||
auxAccepted,
|
||||
parentAccepted
|
||||
].join(':'), function (err, result) {
|
||||
if (err) {
|
||||
log('error', logSystem, 'Failed inserting block candidate %s \n %j', [candidateHash, err]);
|
||||
@@ -1103,7 +1120,7 @@ function processShare (miner, job, blockTemplate, params) {
|
||||
'Block %s found at height %d by miner %s@%s - submit result: %j',
|
||||
[blockFastHash.substr(0, 6), job.height, miner.login, miner.ip, result]
|
||||
);
|
||||
recordShareData(miner, job, hashDiff.toString(), true, blockFastHash, shareType, blockTemplate, acceptedBlockMeta);
|
||||
recordShareData(miner, job, hashDiff.toString(), true, blockFastHash, shareType, blockTemplate, acceptedBlockMeta, result);
|
||||
}
|
||||
}, miningBackends.getMiningRpcConfig(), submitHeaders);
|
||||
} else if (hashDiff < jobDifficulty) {
|
||||
|
||||
Reference in New Issue
Block a user