Skip to content

Commit

Permalink
Implemented support for external work server
Browse files Browse the repository at this point in the history
  • Loading branch information
Joohansson committed Apr 2, 2021
1 parent a45d102 commit b22275a
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 9 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,10 @@ The proxy server is configured via the **settings.json** file found in the serve
* **use_tokens** If activating the token system for purchase via Nano [true/false] (more information further down)
* **use_websocket** If activating the websocket system [true/false] (more information further down)
* **use_cors** If handling cors policy here, if not taken care of in upstream proxy (cors_whitelist=[] means allow ANY ORIGIN)
* **use_dpow** If allow work_generate to be done by dPoW instead of local node. Work will consume 10 token points. If "difficulty" is not provided with the work_generate request the "network current" will be used. (bpow will be used primary with fallback to dpow) (requires work_generate in allowed_commands and credentials to be set in pow_creds.json)
* **use_bpow** If allow work_generate to be done by BoomPoW intead of local node. Work will consume 10 token points. If "difficulty" is not provided with the work_generate request the "network current" will be used. (bpow will be used primary with fallback to dpow) (requires work_generate in allowed_commands and credentials to be set in pow_creds.json)
* **use_dpow** If allow work_generate to be done by dPoW instead of local node. Work will consume 10 token points. If "difficulty" is not provided with the work_generate request the "network current" will be used. (The priority order is bpow > dpow > work server. If all three are set to false, it will use the node to generate work) (requires work_generate in allowed_commands and credentials to be set in pow_creds.json)
* **use_bpow** If allow work_generate to be done by BoomPoW intead of local node. Work will consume 10 token points. If "difficulty" is not provided with the work_generate request the "network current" will be used. (The priority order is bpow > dpow > work server. If all three are set to false, it will use the node to generate work) (requires work_generate in allowed_commands and credentials to be set in pow_creds.json)
* **use_work_server** If allow work_generate to be done by an external work server intead of local node. Work will consume 10 token points. If "difficulty" is not provided with the work_generate request the "network current" will be used. (The priority order is bpow > dpow > work server. If all three are set to false, it will use the node to generate work) (requires work_generate in allowed_commands and url to be set in pow_creds.json). [true/false]
* **use_work_peers** If the node is used to generate work (dpow, bpow and work server all set to false) this will set the "use_peers" to true and let the node use its internally configured work peers [true/false]
* **disable_watch_work** Forcefully set watch_work=false for process calls (to block node from doing rework) [true/false]
* **https_cert:** File path for pub cert file (requires <use_https>) [absolute path string]
* **https_key:** File path for private key file (requires <use_https>) [absolute path string]
Expand Down
4 changes: 4 additions & 0 deletions pow_creds.json.default
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,9 @@
"bpow": {
"user": "user",
"key": "key"
},
"work_server": {
"url": "http://127.0.0.1",
"port": "55555"
}
}
1 change: 1 addition & 0 deletions settings.json.default
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"use_cors": true,
"use_dpow": false,
"use_bpow": false,
"use_work_server": false,
"use_work_peers": false,
"disable_watch_work": false,
"enable_prometheus_for_ips": [],
Expand Down
3 changes: 2 additions & 1 deletion src/__test__/proxy_default.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const expectedDefaultSettings = [
'Use websocket system: false',
'Use dPoW: false',
'Use bPoW: false',
'Use work server: false',
'Use work peers: false',
'Disabled watch_work for process: false',
'Listen on http: true',
Expand All @@ -31,6 +32,6 @@ test('log proxy settings with no config', () => {
let settings: string[] = []
const readSettings: ProxySettings = readProxySettings('path-does-not-exist')
proxyLogSettings((setting: string) => settings.push(setting), readSettings)
expect(settings.length).toBe(24);
expect(settings.length).toBe(25);
expect(settings).toStrictEqual(expectedDefaultSettings)
});
3 changes: 2 additions & 1 deletion src/__test__/proxy_file.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const expectedSettingsWithFile = [
'Use websocket system: false',
'Use dPoW: false',
'Use bPoW: false',
'Use work server: false',
'Use work peers: false',
'Disabled watch_work for process: false',
'Listen on http: true',
Expand Down Expand Up @@ -95,7 +96,7 @@ test('log proxy settings with default config from file', () => {
let settings: string[] = []
const readSettings = readProxySettings(getTestPath(settingsFilePath))
proxyLogSettings((setting: string) => settings.push(setting), readSettings)
expect(settings.length).toBe(29);
expect(settings.length).toBe(30);
expect(settings).toStrictEqual(expectedSettingsWithFile)
})

Expand Down
8 changes: 8 additions & 0 deletions src/pow-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@ interface UserKeyPair {
key: string;
}

interface ServerPair {
url: string;
port: string;
}

export interface PowSettings {
dpow?: UserKeyPair
bpow?: UserKeyPair
work_server?: ServerPair
}

/** Reads proof-of-work settings from file */
Expand All @@ -18,13 +24,15 @@ export function readPowSettings(path: string, settings: ProxySettings): PowSetti
return {
dpow: settings.use_dpow ? readSettings.dpow : undefined,
bpow: settings.use_bpow ? readSettings.bpow : undefined,
work_server: settings.use_work_server ? readSettings.work_server : undefined,
}
}
catch(e) {
console.log("Could not read pow_creds.json", e)
return {
dpow: undefined,
bpow: undefined,
work_server: undefined,
}
}
}
8 changes: 6 additions & 2 deletions src/proxy-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,12 @@ export default interface ProxySettings {
use_websocket: boolean;
// if handling cors policy here, if not taken care of in upstream proxy (cors_whitelist=[] means allow ANY ORIGIN)
use_cors: boolean;
// if allow work_generate to be done by dPoW instead of local node. Work will consume 10 token points. If "difficulty" is not provided with the work_generate request the "network current" will be used. (bpow will be used primary to dpow) (requires work_generate in allowed_commands and credentials to be set in pow_creds.json)
// if allow work_generate to be done by dPoW instead of local node. Work will consume 10 token points. If "difficulty" is not provided with the work_generate request the "network current" will be used. (The priority order is bpow > dpow > work server. If all three are set to false, it will use the node to generate work) (requires work_generate in allowed_commands and credentials to be set in pow_creds.json)
use_dpow: boolean;
// if allow work_generate to be done by BoomPoW intead of local node. Work will consume 10 token points. If "difficulty" is not provided with the work_generate request the "network current" will be used. (bpow will be used primary to dpow) (requires work_generate in allowed_commands and credentials to be set in pow_creds.json)
// if allow work_generate to be done by BoomPoW intead of local node. Work will consume 10 token points. If "difficulty" is not provided with the work_generate request the "network current" will be used. (The priority order is bpow > dpow > work server. If all three are set to false, it will use the node to generate work) (requires work_generate in allowed_commands and credentials to be set in pow_creds.json)
use_bpow: boolean;
// if allow work_generate to be done by external work server instead of local node. Work will consume 10 token points. If "difficulty" is not provided with the work_generate request the "network current" will be used. (The priority order is bpow > dpow > work server. If all three are set to false, it will use the node to generate work) (requires work_generate in allowed_commands)
use_work_server: boolean;
// if allow work_generate implicitly add "use_peers": "true" to the request to use work_peers configured in the nano node.
use_work_peers: boolean;
// file path for pub cert file
Expand Down Expand Up @@ -136,6 +138,7 @@ export function proxyLogSettings(logger: (...data: any[]) => void, settings: Pro
logger("Use websocket system: " + settings.use_websocket)
logger("Use dPoW: " + settings.use_dpow)
logger("Use bPoW: " + settings.use_bpow)
logger("Use work server: " + settings.use_work_server)
logger("Use work peers: " + settings.use_work_peers)
logger("Disabled watch_work for process: " + settings.disable_watch_work)
logger("Listen on http: " + settings.use_http)
Expand Down Expand Up @@ -199,6 +202,7 @@ export function readProxySettings(settingsPath: string): ProxySettings {
use_cors: true,
use_dpow: false,
use_bpow: false,
use_work_server: false,
use_work_peers: false,
https_cert: '',
https_key: '',
Expand Down
39 changes: 36 additions & 3 deletions src/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -693,9 +693,10 @@ async function processRequest(query: ProxyRPCRequest, req: Request, res: Respons
}

// Handle work generate via dpow and/or bpow
if (query.action === 'work_generate' && (settings.use_dpow || settings.use_bpow || settings.use_work_peers)) {
if (query.action === 'work_generate' && (settings.use_dpow || settings.use_bpow || settings.use_work_server || settings.use_work_peers)) {
if (query.hash) {
let bpow_failed = false
let dpow_failed = false
// Only set difficulty from live network if not requested or if it was exactly default
if (!query.difficulty || query.difficulty === work_threshold_default || query.difficulty === work_threshold_receive_default) {
query.difficulty = await getLatestDifficulty(query.difficulty)
Expand All @@ -705,7 +706,7 @@ async function processRequest(query: ProxyRPCRequest, req: Request, res: Respons
query.timeout = work_default_timeout
}

if (settings.use_work_peers && !settings.use_bpow && !settings.use_dpow) {
if (settings.use_work_peers && !settings.use_bpow && !settings.use_dpow && !settings.use_work_server) {
//Only add use_peers when _NOT_ using any of bpow or dpow.
query.use_peers = "true"
}
Expand Down Expand Up @@ -761,10 +762,42 @@ async function processRequest(query: ProxyRPCRequest, req: Request, res: Respons
if (data.error) {
logThis("dPoW failed: " + data.error, log_levels.warning)
}
return res.json(appendRateLimiterStatus(res, data)) // sending back json response (regardless if timeout error)
if ((data.error) || !(data.work)) {
dpow_failed = true
if (!settings.use_work_server) {
return res.json(appendRateLimiterStatus(res, data)) // forward error if not retrying with work server
}
}
else if (data.work) {
return res.json(appendRateLimiterStatus(res, data)) // sending back json response (regardless if timeout error)
}
}
catch(err) {
dpow_failed = true
logThis("Dpow connection error: " + err.toString(), log_levels.warning)
if (!settings.use_work_server) {
return res.status(500).json({error: err.toString()})
}
}
}
// Use work server only if not already used bpow/dpow or bpow/dpow timed out
if (((!settings.use_bpow && !settings.use_dpow) || (bpow_failed || dpow_failed)) && settings.use_work_server && powSettings.work_server) {
logThis("Requesting work using work server with diff: " + query.difficulty, log_levels.info)

try {
let data: ProcessDataResponse = await Tools.postData(query, powSettings.work_server.url+':'+powSettings.work_server.port, work_default_timeout*1000*2)
data.difficulty = query.difficulty
data.multiplier = multiplierFromDifficulty(data.difficulty, work_threshold_default)
if (tokens_left != null) {
data.tokens_total = tokens_left
}
if (data.error) {
logThis("work server failed: " + data.error, log_levels.warning)
}
return res.json(appendRateLimiterStatus(res, data)) // sending back json response (regardless if timeout error)
}
catch(err) {
logThis("Work server connection error: " + err.toString(), log_levels.warning)
return res.status(500).json({error: err.toString()})
}
}
Expand Down

0 comments on commit b22275a

Please sign in to comment.