cryptonote-universal-pool/redisBlocksUpgrade.js

191 lines
5.9 KiB
JavaScript

/*
This script converts the block data in redis from the old format (v0.99.0.6 and earlier) to the new format
used in v0.99.1+
*/
var util = require('util');
var async = require('async');
var redis = require('redis');
require('./lib/configReader.js');
var apiInterfaces = require('./lib/apiInterfaces.js')(config.daemon, config.wallet);
function log(severity, system, text, data){
var formattedMessage = text;
if (data) {
data.unshift(text);
formattedMessage = util.format.apply(null, data);
}
console.log(severity + ': ' + formattedMessage);
}
var logSystem = 'reward script';
var redisClient = redis.createClient(config.redis.port, config.redis.host);
function getTotalShares(height, callback){
redisClient.hgetall(config.coin + ':shares:round' + height, function(err, workerShares){
if (err) {
callback(err);
return;
}
var totalShares = Object.keys(workerShares).reduce(function(p, c){
return p + parseInt(workerShares[c])
}, 0);
callback(null, totalShares);
});
}
async.series([
function(callback){
redisClient.smembers(config.coin + ':blocksUnlocked', function(error, result){
if (error){
log('error', logSystem, 'Error trying to get unlocke blocks from redis %j', [error]);
callback();
return;
}
if (result.length === 0){
log('info', logSystem, 'No unlocked blocks in redis');
callback();
return;
}
var blocks = result.map(function(item){
var parts = item.split(':');
return {
height: parseInt(parts[0]),
difficulty: parts[1],
hash: parts[2],
time: parts[3],
shares: parts[4],
orphaned: 0
};
});
async.map(blocks, function(block, mapCback){
apiInterfaces.rpcDaemon('getblockheaderbyheight', {height: block.height}, function(error, result){
if (error){
log('error', logSystem, 'Error with getblockheaderbyheight RPC request for block %s - %j', [block.serialized, error]);
mapCback(null, block);
return;
}
if (!result.block_header){
log('error', logSystem, 'Error with getblockheaderbyheight, no details returned for %s - %j', [block.serialized, result]);
mapCback(null, block);
return;
}
var blockHeader = result.block_header;
block.reward = blockHeader.reward;
mapCback(null, block);
});
}, function(err, blocks){
if (blocks.length === 0){
log('info', logSystem, 'No unlocked blocks');
callback();
return;
}
var zaddCommands = [config.coin + ':blocks:matured'];
for (var i = 0; i < blocks.length; i++){
var block = blocks[i];
zaddCommands.push(block.height);
zaddCommands.push([
block.hash,
block.time,
block.difficulty,
block.shares,
block.orphaned,
block.reward
].join(':'));
}
redisClient.zadd(zaddCommands, function(err, result){
if (err){
console.log('failed zadd ' + JSON.stringify(err));
callback();
return;
}
console.log('successfully converted unlocked blocks to matured blocks');
callback();
});
});
});
},
function(callback){
redisClient.smembers(config.coin + ':blocksPending', function(error, result) {
if (error) {
log('error', logSystem, 'Error trying to get pending blocks from redis %j', [error]);
callback();
return;
}
if (result.length === 0) {
log('info', logSystem, 'No pending blocks in redis');
callback();
return;
}
async.map(result, function(item, mapCback){
var parts = item.split(':');
var block = {
height: parseInt(parts[0]),
difficulty: parts[1],
hash: parts[2],
time: parts[3],
serialized: item
};
getTotalShares(block.height, function(err, shares){
block.shares = shares;
mapCback(null, block);
});
}, function(err, blocks){
var zaddCommands = [config.coin + ':blocks:candidates'];
for (var i = 0; i < blocks.length; i++){
var block = blocks[i];
zaddCommands.push(block.height);
zaddCommands.push([
block.hash,
block.time,
block.difficulty,
block.shares
].join(':'));
}
redisClient.zadd(zaddCommands, function(err, result){
if (err){
console.log('failed zadd ' + JSON.stringify(err));
return;
}
console.log('successfully converted pending blocks to block candidates');
});
});
});
}
], function(){
process.exit();
});