Skip to content

Commit b719fde

Browse files
committed
Fix BTC-style reward history sampling
1 parent 84cf7e9 commit b719fde

2 files changed

Lines changed: 54 additions & 3 deletions

File tree

lib/coins/core/factories.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ function voutPaysAddress(vout, address) {
6666
return scriptPubKey.address === address;
6767
}
6868

69-
function parseBtcReward(block, config, poolAddress) {
69+
function parseBtcReward(block, config, poolAddress, isOurBlock) {
7070
let reward = 0;
71-
const sumPoolVout = config.headerRewardMode === "sum-pool-vout";
71+
const sumPoolVout = isOurBlock && config.headerRewardMode === "sum-pool-vout";
7272
for (const vout of block.tx[0].vout) {
7373
if (sumPoolVout) {
7474
if (voutPaysAddress(vout, poolAddress)) reward += vout.value;
@@ -250,7 +250,7 @@ function createBtcRpc(overrides) {
250250
config.getAnyBlockHeaderByHash = function getAnyBlockHeaderByHash(ctx) {
251251
ctx.runtime.support.rpcPortDaemon2(ctx.port, "", { method: "getblock", params: [ctx.blockHash, 2] }, function onBlock(body) {
252252
if (!body || !body.result || !(body.result.tx instanceof Array) || body.result.tx.length < 1) return ctx.callback(true, body);
253-
return ctx.callback(null, parseBtcReward(body.result, config, ctx.runtime.getPoolAddress(ctx.profile)));
253+
return ctx.callback(null, parseBtcReward(body.result, config, ctx.runtime.getPoolAddress(ctx.profile), ctx.isOurBlock));
254254
}, ctx.noErrorReport);
255255
};
256256

tests/pool/coin/basics.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,57 @@ test("BTC-style block rewards only credit coinbase outputs paid to the pool addr
373373
}
374374
});
375375

376+
test("BTC-style network tip rewards fall back to max coinbase output for history sampling", async () => {
377+
const coinFuncs = global.coinFuncs.__realCoinFuncs;
378+
const cases = [
379+
{ coin: "RVN", port: 8766, addressKey: "address_8766" },
380+
{ coin: "XNA", port: 19001, addressKey: "address_19001" }
381+
];
382+
const originalRpcPortDaemon2 = global.support.rpcPortDaemon2;
383+
384+
try {
385+
for (const entry of cases) {
386+
const poolAddress = "POOL_" + entry.coin + "_ADDRESS";
387+
global.config.pool[entry.addressKey] = poolAddress;
388+
global.support.rpcPortDaemon2 = function rpcPortDaemon2(port, method, params, callback) {
389+
assert.equal(port, entry.port);
390+
assert.equal(method, "");
391+
assert.deepEqual(params, { method: "getblock", params: [entry.coin.toLowerCase() + "-tip", 2] });
392+
callback({
393+
result: {
394+
difficulty: 2,
395+
tx: [{
396+
vout: [
397+
{ n: 0, value: 12.5, scriptPubKey: { addresses: ["OTHER_MINER"] } },
398+
{ n: 1, value: 3, scriptPubKey: { address: poolAddress } },
399+
{ n: 2, value: 1.25, scriptPubKey: { addresses: ["GOVERNANCE_ADDRESS"] } }
400+
]
401+
}]
402+
}
403+
});
404+
};
405+
406+
try {
407+
const header = await new Promise((resolve, reject) => {
408+
coinFuncs.getPortAnyBlockHeaderByHash(entry.port, entry.coin.toLowerCase() + "-tip", false, (err, body) => {
409+
if (err) return reject(new Error("unexpected " + entry.coin + " network tip header error"));
410+
return resolve(body);
411+
});
412+
});
413+
414+
assert.equal(header.reward, 1250000000);
415+
} finally {
416+
delete global.config.pool[entry.addressKey];
417+
}
418+
}
419+
} finally {
420+
global.support.rpcPortDaemon2 = originalRpcPortDaemon2;
421+
cases.forEach(function clearAddress(entry) {
422+
delete global.config.pool[entry.addressKey];
423+
});
424+
}
425+
});
426+
376427
test("BlockTemplate derives dual-main candidate difficulty from the lowest chain difficulty", () => {
377428
const coinFuncs = global.coinFuncs.__realCoinFuncs;
378429
const originalGetAuxChainXTM = global.coinFuncs.getAuxChainXTM;

0 commit comments

Comments
 (0)