Skip to content

Commit ecfcde0

Browse files
committed
add payment only runner
1 parent 60bebda commit ecfcde0

File tree

1 file changed

+216
-0
lines changed

1 file changed

+216
-0
lines changed

pay.js

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
var fs = require('fs');
2+
var path = require('path');
3+
var os = require('os');
4+
var cluster = require('cluster');
5+
6+
var async = require('async');
7+
8+
var PoolLogger = require('./libs/logUtil.js');
9+
var PaymentProcessor = require('./libs/paymentProcessor.js');
10+
11+
var algos = require('stratum-pool/lib/algoProperties.js');
12+
13+
JSON.minify = JSON.minify || require("node-json-minify");
14+
15+
if (!fs.existsSync('config.json')){
16+
console.log('config.json file does not exist. Read the installation/setup instructions.');
17+
return;
18+
}
19+
20+
var portalConfig = JSON.parse(JSON.minify(fs.readFileSync("config.json", {encoding: 'utf8'})));
21+
var poolConfigs;
22+
23+
24+
var logger = new PoolLogger({
25+
logLevel: portalConfig.logLevel,
26+
logColors: portalConfig.logColors
27+
});
28+
29+
30+
31+
32+
try {
33+
require('newrelic');
34+
if (cluster.isMaster)
35+
logger.debug('NewRelic', 'Monitor', 'New Relic initiated');
36+
} catch(e) {}
37+
38+
39+
//Try to give process ability to handle 100k concurrent connections
40+
try{
41+
var posix = require('posix');
42+
try {
43+
posix.setrlimit('nofile', { soft: 100000, hard: 100000 });
44+
}
45+
catch(e){
46+
if (cluster.isMaster)
47+
logger.warning('POSIX', 'Connection Limit', '(Safe to ignore) Must be ran as root to increase resource limits');
48+
}
49+
finally {
50+
// Find out which user used sudo through the environment variable
51+
var uid = parseInt(process.env.SUDO_UID);
52+
// Set our server's uid to that user
53+
if (uid) {
54+
process.setuid(uid);
55+
logger.debug('POSIX', 'Connection Limit', 'Raised to 100K concurrent connections, now running as non-root user: ' + process.getuid());
56+
}
57+
}
58+
}
59+
catch(e){
60+
if (cluster.isMaster)
61+
logger.debug('POSIX', 'Connection Limit', '(Safe to ignore) POSIX module not installed and resource (connection) limit was not raised');
62+
}
63+
64+
65+
if (cluster.isWorker){
66+
67+
switch(process.env.workerType){
68+
case 'pool':
69+
new PoolWorker(logger);
70+
break;
71+
case 'paymentProcessor':
72+
new PaymentProcessor(logger);
73+
break;
74+
case 'website':
75+
new Website(logger);
76+
break;
77+
case 'profitSwitch':
78+
new ProfitSwitch(logger);
79+
break;
80+
}
81+
82+
return;
83+
}
84+
85+
86+
//Read all pool configs from pool_configs and join them with their coin profile
87+
var buildPoolConfigs = function(){
88+
var configs = {};
89+
var configDir = 'pool_configs/';
90+
91+
var poolConfigFiles = [];
92+
93+
94+
/* Get filenames of pool config json files that are enabled */
95+
fs.readdirSync(configDir).forEach(function(file){
96+
if (!fs.existsSync(configDir + file) || path.extname(configDir + file) !== '.json') return;
97+
var poolOptions = JSON.parse(JSON.minify(fs.readFileSync(configDir + file, {encoding: 'utf8'})));
98+
if (!poolOptions.enabled) return;
99+
poolOptions.fileName = file;
100+
poolConfigFiles.push(poolOptions);
101+
});
102+
103+
104+
/* Ensure no pool uses any of the same ports as another pool */
105+
for (var i = 0; i < poolConfigFiles.length; i++){
106+
var ports = Object.keys(poolConfigFiles[i].ports);
107+
for (var f = 0; f < poolConfigFiles.length; f++){
108+
if (f === i) continue;
109+
var portsF = Object.keys(poolConfigFiles[f].ports);
110+
for (var g = 0; g < portsF.length; g++){
111+
if (ports.indexOf(portsF[g]) !== -1){
112+
logger.error('Master', poolConfigFiles[f].fileName, 'Has same configured port of ' + portsF[g] + ' as ' + poolConfigFiles[i].fileName);
113+
process.exit(1);
114+
return;
115+
}
116+
}
117+
118+
if (poolConfigFiles[f].coin === poolConfigFiles[i].coin){
119+
logger.error('Master', poolConfigFiles[f].fileName, 'Pool has same configured coin file coins/' + poolConfigFiles[f].coin + ' as ' + poolConfigFiles[i].fileName + ' pool');
120+
process.exit(1);
121+
return;
122+
}
123+
124+
}
125+
}
126+
127+
128+
poolConfigFiles.forEach(function(poolOptions){
129+
130+
poolOptions.coinFileName = poolOptions.coin;
131+
132+
var coinFilePath = 'coins/' + poolOptions.coinFileName;
133+
if (!fs.existsSync(coinFilePath)){
134+
logger.error('Master', poolOptions.coinFileName, 'could not find file: ' + coinFilePath);
135+
return;
136+
}
137+
138+
var coinProfile = JSON.parse(JSON.minify(fs.readFileSync(coinFilePath, {encoding: 'utf8'})));
139+
poolOptions.coin = coinProfile;
140+
poolOptions.coin.name = poolOptions.coin.name.toLowerCase();
141+
142+
if (poolOptions.coin.name in configs){
143+
144+
logger.error('Master', poolOptions.fileName, 'coins/' + poolOptions.coinFileName
145+
+ ' has same configured coin name ' + poolOptions.coin.name + ' as coins/'
146+
+ configs[poolOptions.coin.name].coinFileName + ' used by pool config '
147+
+ configs[poolOptions.coin.name].fileName);
148+
149+
process.exit(1);
150+
return;
151+
}
152+
153+
for (var option in portalConfig.defaultPoolConfigs){
154+
if (!(option in poolOptions)){
155+
var toCloneOption = portalConfig.defaultPoolConfigs[option];
156+
var clonedOption = {};
157+
if (toCloneOption.constructor === Object) {
158+
Object.assign(clonedOption, toCloneOption);
159+
} else {
160+
clonedOption = toCloneOption;
161+
}
162+
poolOptions[option] = clonedOption;
163+
}
164+
}
165+
166+
167+
configs[poolOptions.coin.name] = poolOptions;
168+
169+
if (!(coinProfile.algorithm in algos)){
170+
logger.error('Master', coinProfile.name, 'Cannot run a pool for unsupported algorithm "' + coinProfile.algorithm + '"');
171+
delete configs[poolOptions.coin.name];
172+
}
173+
174+
});
175+
return configs;
176+
};
177+
178+
179+
180+
var startPaymentProcessor = function(){
181+
182+
var enabledForAny = false;
183+
for (var pool in poolConfigs){
184+
var p = poolConfigs[pool];
185+
var enabled = p.enabled && p.paymentProcessing && p.paymentProcessing.enabled;
186+
if (enabled){
187+
enabledForAny = true;
188+
break;
189+
}
190+
}
191+
192+
console.log(poolConfigs);
193+
194+
if (!enabledForAny)
195+
return;
196+
197+
var worker = cluster.fork({
198+
workerType: 'paymentProcessor',
199+
pools: JSON.stringify(poolConfigs)
200+
});
201+
worker.on('exit', function(code, signal){
202+
logger.error('Master', 'Payment Processor', 'Payment processor died, spawning replacement...');
203+
setTimeout(function(){
204+
startPaymentProcessor(poolConfigs);
205+
}, 2000);
206+
});
207+
};
208+
209+
210+
(function init(){
211+
212+
poolConfigs = buildPoolConfigs();
213+
214+
startPaymentProcessor();
215+
216+
})();

0 commit comments

Comments
 (0)