From c638096023017d1085bce6e67cdeab1cb0a8887a Mon Sep 17 00:00:00 2001 From: Alexander Leitner Date: Thu, 6 Jul 2017 15:11:20 -0400 Subject: [PATCH 01/13] Validate format of storage size --- bin/storjshare-create.js | 7 +++++++ lib/api.js | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/bin/storjshare-create.js b/bin/storjshare-create.js index 35b35de..efea891 100755 --- a/bin/storjshare-create.js +++ b/bin/storjshare-create.js @@ -84,6 +84,13 @@ if (!storjshare_create.logdir) { ); } +if (storjshare_create.size && + !storjshare_create.size.match(/[0-9]+(T|M|G|K)?B/g)) { + console.error('\n Invalid storage size specified: '+ + storjshare_create.size); + process.exit(1); +} + let exampleConfigPath = path.join(__dirname, '../example/farmer.config.json'); let exampleConfigString = fs.readFileSync(exampleConfigPath).toString(); diff --git a/lib/api.js b/lib/api.js index c450845..19e8723 100644 --- a/lib/api.js +++ b/lib/api.js @@ -109,6 +109,12 @@ class RPC { this._log(`attempting to start share with config at path ${configPath}`); + if (!config.size.match(/[0-9]+(T|M|G|K)?B/g)) { + return callback( + new Error(`Invalid Storage size specified: $(config.size)`) + ); + } + if (this.shares.has(nodeId) && this.shares.get(nodeId).readyState === 1) { return callback(new Error(`share ${nodeId} is already running`)); } From 2a17b0b266c7e601d25140aacc7bc2719dbfd6d4 Mon Sep 17 00:00:00 2001 From: Alexander Leitner Date: Thu, 6 Jul 2017 15:22:57 -0400 Subject: [PATCH 02/13] Oops used the wrong variable --- lib/api.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/api.js b/lib/api.js index 19e8723..835042d 100644 --- a/lib/api.js +++ b/lib/api.js @@ -109,9 +109,11 @@ class RPC { this._log(`attempting to start share with config at path ${configPath}`); - if (!config.size.match(/[0-9]+(T|M|G|K)?B/g)) { + if (!share.config.storageAllocation.match(/[0-9]+(T|M|G|K)?B/g)) { return callback( - new Error(`Invalid Storage size specified: $(config.size)`) + new Error('Invalid Storage size specified: '+ + share.config.storageAllocation + ) ); } From aedd5661f9210c32cfc78d4dec56c7a308a1be8c Mon Sep 17 00:00:00 2001 From: Alexander Leitner Date: Thu, 6 Jul 2017 16:02:56 -0400 Subject: [PATCH 03/13] Use vi by defult otherwise don't use anything --- bin/storjshare-create.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/storjshare-create.js b/bin/storjshare-create.js index efea891..de0c2b2 100755 --- a/bin/storjshare-create.js +++ b/bin/storjshare-create.js @@ -18,9 +18,9 @@ const defaultConfig = JSON.parse(stripJsonComments(fs.readFileSync( path.join(__dirname, '../example/farmer.config.json') ).toString())); -function vimIsInstalled() { +function viIsInstalled() { try { - execSync('which vim'); + execSync('which vi'); } catch (err) { return false; } @@ -166,7 +166,7 @@ if (!storjshare_create.noedit) { // NB: Not all distros ship with vim, so let's use GNU Nano editor: process.platform === 'win32' ? null - : (vimIsInstalled() ? 'vim' : 'nano') + : (viIsInstalled() ? 'vi' : null) }, () => { console.log(' ...'); console.log(` * use new config: storjshare start --config ${outfile}`); From 42a02b15c4aee763a98dff341b43e3b4f7a0e35c Mon Sep 17 00:00:00 2001 From: Alexander Leitner Date: Fri, 7 Jul 2017 12:52:31 -0400 Subject: [PATCH 04/13] Check vim, then nano, then default --- bin/storjshare-create.js | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/bin/storjshare-create.js b/bin/storjshare-create.js index de0c2b2..ca28f2b 100755 --- a/bin/storjshare-create.js +++ b/bin/storjshare-create.js @@ -18,14 +18,27 @@ const defaultConfig = JSON.parse(stripJsonComments(fs.readFileSync( path.join(__dirname, '../example/farmer.config.json') ).toString())); -function viIsInstalled() { - try { - execSync('which vi'); - } catch (err) { - return false; +function whichEditor() { + + const editors = ['vim', 'nano']; + + function checkIsInstalled(editor) { + try { + execSync('which ' + editor); + } catch (err) { + return false; + } + + return true; + }; + + for (let i = 0; i < editors.length; i++) { + if (checkIsInstalled(editors[i])) { + return editors[i]; + }; } - return true; + return null; } storjshare_create @@ -166,7 +179,7 @@ if (!storjshare_create.noedit) { // NB: Not all distros ship with vim, so let's use GNU Nano editor: process.platform === 'win32' ? null - : (viIsInstalled() ? 'vi' : null) + : whichEditor() }, () => { console.log(' ...'); console.log(` * use new config: storjshare start --config ${outfile}`); From 2104eb9db3d4a61a7ea434a30d57c36bc331066e Mon Sep 17 00:00:00 2001 From: Alexander Leitner Date: Fri, 7 Jul 2017 13:32:32 -0400 Subject: [PATCH 05/13] Add test for failing spac specification --- bin/storjshare-create.js | 6 +++--- lib/api.js | 9 +++++---- test/api.unit.js | 35 ++++++++++++++++++++++++++++++++--- 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/bin/storjshare-create.js b/bin/storjshare-create.js index ca28f2b..6562924 100755 --- a/bin/storjshare-create.js +++ b/bin/storjshare-create.js @@ -20,7 +20,7 @@ const defaultConfig = JSON.parse(stripJsonComments(fs.readFileSync( function whichEditor() { - const editors = ['vim', 'nano']; + const editors = ['vi', 'nano']; function checkIsInstalled(editor) { try { @@ -30,12 +30,12 @@ function whichEditor() { } return true; - }; + } for (let i = 0; i < editors.length; i++) { if (checkIsInstalled(editors[i])) { return editors[i]; - }; + } } return null; diff --git a/lib/api.js b/lib/api.js index 835042d..a7a910f 100644 --- a/lib/api.js +++ b/lib/api.js @@ -71,6 +71,7 @@ class RPC { } catch (err) { throw new Error(err.message.toLowerCase()); } + return config; } @@ -109,6 +110,10 @@ class RPC { this._log(`attempting to start share with config at path ${configPath}`); + if (this.shares.has(nodeId) && this.shares.get(nodeId).readyState === 1) { + return callback(new Error(`share ${nodeId} is already running`)); + } + if (!share.config.storageAllocation.match(/[0-9]+(T|M|G|K)?B/g)) { return callback( new Error('Invalid Storage size specified: '+ @@ -117,10 +122,6 @@ class RPC { ); } - if (this.shares.has(nodeId) && this.shares.get(nodeId).readyState === 1) { - return callback(new Error(`share ${nodeId} is already running`)); - } - utils.validateAllocation(share.config, (err) => { if (err) { return callback(new Error(err.message.toLowerCase())); diff --git a/test/api.unit.js b/test/api.unit.js index d3249dc..671f68d 100644 --- a/test/api.unit.js +++ b/test/api.unit.js @@ -137,7 +137,9 @@ describe('class:RPC', function() { let _RPC = proxyquire('../lib/api', { fs: { statSync: sinon.stub(), - readFileSync: sinon.stub().returns(Buffer.from('{}')) + readFileSync: sinon.stub().returns( + Buffer.from('{"storageAllocation":"23GB"}') + ) }, './utils': { validate: sinon.stub(), @@ -154,6 +156,29 @@ describe('class:RPC', function() { }); }); + it('should callback error if invalid space specified', function(done) { + let _RPC = proxyquire('../lib/api', { + fs: { + statSync: sinon.stub(), + readFileSync: sinon.stub().returns( + Buffer.from('{"storageAllocation":"23G"}') + ) + }, + './utils': { + validate: sinon.stub(), + validateAllocation: sinon.stub().callsArgWith( + 1, + new Error('Bad space') + ) + } + }); + let rpc = new _RPC({ loggerVerbosity: 0 }); + rpc.start('path/to/config', function(err) { + expect(err.message).to.equal('Invalid Storage size specified: 23G'); + done(); + }); + }); + it('should fork the share and setup listeners', function(done) { let _proc = new EventEmitter(); _proc.stdout = new Readable({ read: () => null }); @@ -169,7 +194,9 @@ describe('class:RPC', function() { statSync: sinon.stub().returns({ isDirectory: () => true }), - readFileSync: sinon.stub().returns(Buffer.from('{}')) + readFileSync: sinon.stub().returns( + Buffer.from('{"storageAllocation":"23GB"}') + ) }, './utils': { validate: sinon.stub(), @@ -217,7 +244,9 @@ describe('class:RPC', function() { statSync: sinon.stub().returns({ isDirectory: () => false }), - readFileSync: sinon.stub().returns(Buffer.from('{}')) + readFileSync: sinon.stub().returns( + Buffer.from('{"storageAllocation":"23GB"}') + ) }, './utils': { validate: sinon.stub(), From 45de64deb0f6081d6d752dbae2854f997f43cc74 Mon Sep 17 00:00:00 2001 From: Alexander Leitner Date: Mon, 10 Jul 2017 12:05:40 -0400 Subject: [PATCH 06/13] Validate private key before starting share --- lib/api.js | 10 ++++++++-- lib/utils.js | 15 +++++++++++++++ test/api.unit.js | 22 ++++++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/lib/api.js b/lib/api.js index a7a910f..6b95452 100644 --- a/lib/api.js +++ b/lib/api.js @@ -1,7 +1,6 @@ 'use strict'; const async = require('async'); -const storj = require('storj-lib'); const fs = require('fs'); const {statSync, readFileSync} = require('fs'); const stripJsonComments = require('strip-json-comments'); @@ -83,6 +82,7 @@ class RPC { * @see https://storj.github.io/core/FarmerInterface.html */ start(configPath, callback, unsafeFlag=false) { + /*jshint maxcomplexity:7 */ let config = null; if (this.running >= cpus().length && !unsafeFlag) { @@ -95,7 +95,13 @@ class RPC { return callback(err); } - const nodeId = storj.KeyPair(config.networkPrivateKey).getNodeID(); + const nodeId = utils.getNodeID(config.networkPrivateKey); + if (nodeId === null) { + return callback(new Error('Invalid Private Key')); + } + console.log(config.networkPrivateKey); + console.log(nodeId); + const share = this.shares.get(nodeId) || { config: config, meta: { diff --git a/lib/utils.js b/lib/utils.js index 110a589..a7a09de 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -237,3 +237,18 @@ exports.connectToDaemon = function(port, callback, hostname = null) { sock.on('remote', (rpc) => callback(rpc, sock)); }; + +/** + * Get node Id by Private Key + * @param {String} privateKey + */ + exports.getNodeID = function(privateKey) { + let nodeId = null; + try { + nodeId = storj.KeyPair(privateKey).getNodeID(); + } catch (err) { + return null; + } + + return nodeId; +}; diff --git a/test/api.unit.js b/test/api.unit.js index 671f68d..41f4099 100644 --- a/test/api.unit.js +++ b/test/api.unit.js @@ -179,6 +179,28 @@ describe('class:RPC', function() { }); }); + it('should callback error if invalid network Private key', function(done) { + let _RPC = proxyquire('../lib/api', { + fs: { + statSync: sinon.stub(), + readFileSync: sinon.stub().returns( + Buffer.from('{"storageAllocation":"23GB","networkPrivateKey":' + + '"02d2e5fb5a1fe74804bc1ae3b63bb130441cc9b5c877e22' + + '5ea723c24bcea4f3babc123"}') + ) + }, + './utils': { + validate: sinon.stub(), + validateAllocation: sinon.stub() + } + }); + let rpc = new _RPC({ loggerVerbosity: 0 }); + rpc.start('path/to/config', function(err) { + expect(err.message).to.equal('Invalid Private Key'); + done(); + }); + }); + it('should fork the share and setup listeners', function(done) { let _proc = new EventEmitter(); _proc.stdout = new Readable({ read: () => null }); From 39cf60216063f2f254e051f01fdc3e2a3284fbd2 Mon Sep 17 00:00:00 2001 From: Alexander Leitner Date: Mon, 10 Jul 2017 15:18:36 -0400 Subject: [PATCH 07/13] Optional json output when checking storjshare status --- bin/storjshare-status.js | 142 +++++++++++++++++++++++++-------------- 1 file changed, 93 insertions(+), 49 deletions(-) diff --git a/bin/storjshare-status.js b/bin/storjshare-status.js index aa45f1d..7539385 100755 --- a/bin/storjshare-status.js +++ b/bin/storjshare-status.js @@ -13,6 +13,8 @@ storjshare_status .description('prints the status of all managed shares') .option('-r, --remote ', 'hostname and optional port of the daemon') + .option('-j, --json', + 'JSON formatted status of all managed shares') .parse(process.argv); function getColoredValue(status, value) { @@ -47,57 +49,99 @@ if (storjshare_status.remote) { utils.connectToDaemon(port, function(rpc, sock) { rpc.status(function(err, shares) { - let table = new Table({ - head: ['Share', 'Status', 'Uptime', 'Restarts', 'Peers', - 'Contracts', 'Delta', 'Port', 'Shared'], - style: { - head: ['cyan', 'bold'], - border: [] - }, - colWidths: [45, 10, 10, 10, 10, 11, 9, 11, 10] - }); - shares.forEach((share) => { - let status = '?'; - - switch (share.state) { - case 0: - status = colors.gray('stopped'); - break; - case 1: - status = colors.green('running'); - break; - case 2: - status = colors.red('errored'); - break; - default: - status = 'unknown'; + if (storjshare_status.json) { + let json = []; + + for (let i = 0; i < shares.length; i++) { + let share = shares[i]; + + json[i] = {}; + json[i].id = share.id; + + let status = '?'; + + switch (share.state) { + case 0: + status = 'stopped'; + break; + case 1: + status = 'running'; + break; + case 2: + status = 'errored'; + break; + default: + status = 'unknown'; + } + + json[i].status = status; + json[i].configPath = share.config.storagePath; + json[i].uptime = prettyMs(share.meta.uptimeMs); + json[i].restarts = share.meta.numRestarts || 0; + json[i].peers = share.meta.farmerState.totalPeers || 0; + json[i].contracts = fixContractValue( + share.meta.farmerState.contractCount + ); + json[i].delta = share.meta.farmerState.ntpStatus.delta; + json[i].port = share.meta.farmerState.portStatus.listenPort; + json[i].shared = share.meta.farmerState.spaceUsed; + json[i].sharedPercent = share.meta.farmerState.percentUsed; } - let portStatus = share.meta.farmerState.portStatus; - let port = getColoredValue(portStatus.connectionStatus, - portStatus.listenPort); - let connectionType = getColoredValue(portStatus.connectionStatus, - portStatus.connectionType); - - let ntpStatus = getColoredValue(share.meta.farmerState.ntpStatus.status, - share.meta.farmerState.ntpStatus.delta); - - let contracts = fixContractValue(share.meta.farmerState.contractCount); - - table.push([ - `${share.id}\n → ${share.config.storagePath}`, - status, - prettyMs(share.meta.uptimeMs), - share.meta.numRestarts || 0, - share.meta.farmerState.totalPeers || 0, - contracts, - ntpStatus, - port + '\n' + connectionType, - share.meta.farmerState.spaceUsed + '\n' + - `(${share.meta.farmerState.percentUsed}%)` - ]); - }); - console.log('\n' + table.toString()); + console.log(json); + } else { + let table = new Table({ + head: ['Share', 'Status', 'Uptime', 'Restarts', 'Peers', + 'Contracts', 'Delta', 'Port', 'Shared'], + style: { + head: ['cyan', 'bold'], + border: [] + }, + colWidths: [45, 10, 10, 10, 10, 11, 9, 11, 10] + }); + shares.forEach((share) => { + let status = '?'; + + switch (share.state) { + case 0: + status = colors.gray('stopped'); + break; + case 1: + status = colors.green('running'); + break; + case 2: + status = colors.red('errored'); + break; + default: + status = 'unknown'; + } + + let portStatus = share.meta.farmerState.portStatus; + let port = getColoredValue(portStatus.connectionStatus, + portStatus.listenPort); + let connectionType = getColoredValue(portStatus.connectionStatus, + portStatus.connectionType); + + let ntpStatus = getColoredValue(share.meta.farmerState.ntpStatus.status, + share.meta.farmerState.ntpStatus.delta); + + let contracts = fixContractValue(share.meta.farmerState.contractCount); + + table.push([ + `${share.id}\n → ${share.config.storagePath}`, + status, + prettyMs(share.meta.uptimeMs), + share.meta.numRestarts || 0, + share.meta.farmerState.totalPeers || 0, + contracts, + ntpStatus, + port + '\n' + connectionType, + share.meta.farmerState.spaceUsed + '\n' + + `(${share.meta.farmerState.percentUsed}%)` + ]); + }); + console.log('\n' + table.toString()); + } sock.end(); }); }, address); From 736defa5c46ba9e5f2f38abcdcdf3c16ff3d75ef Mon Sep 17 00:00:00 2001 From: Alexander Leitner Date: Mon, 10 Jul 2017 15:25:33 -0400 Subject: [PATCH 08/13] Remove old console logs, fix jshint issues --- bin/storjshare-status.js | 84 ++++++++++++++++++++++------------------ lib/api.js | 2 - 2 files changed, 46 insertions(+), 40 deletions(-) diff --git a/bin/storjshare-status.js b/bin/storjshare-status.js index 7539385..aa45c72 100755 --- a/bin/storjshare-status.js +++ b/bin/storjshare-status.js @@ -47,47 +47,55 @@ if (storjshare_status.remote) { } } -utils.connectToDaemon(port, function(rpc, sock) { - rpc.status(function(err, shares) { - if (storjshare_status.json) { - let json = []; - - for (let i = 0; i < shares.length; i++) { - let share = shares[i]; - - json[i] = {}; - json[i].id = share.id; - - let status = '?'; +// Prepare json formatted status for each share +function prepareJson(shares) { + /*jshint maxcomplexity:7 */ + let json = []; + + for (let i = 0; i < shares.length; i++) { + let share = shares[i]; + + json[i] = {}; + json[i].id = share.id; + + let status = '?'; + + switch (share.state) { + case 0: + status = 'stopped'; + break; + case 1: + status = 'running'; + break; + case 2: + status = 'errored'; + break; + default: + status = 'unknown'; + } - switch (share.state) { - case 0: - status = 'stopped'; - break; - case 1: - status = 'running'; - break; - case 2: - status = 'errored'; - break; - default: - status = 'unknown'; - } + json[i].status = status; + json[i].configPath = share.config.storagePath; + json[i].uptime = prettyMs(share.meta.uptimeMs); + json[i].restarts = share.meta.numRestarts || 0; + json[i].peers = share.meta.farmerState.totalPeers || 0; + json[i].contracts = fixContractValue( + share.meta.farmerState.contractCount + ); + json[i].delta = share.meta.farmerState.ntpStatus.delta; + json[i].port = share.meta.farmerState.portStatus.listenPort; + json[i].shared = share.meta.farmerState.spaceUsed; + json[i].sharedPercent = share.meta.farmerState.percentUsed; + } - json[i].status = status; - json[i].configPath = share.config.storagePath; - json[i].uptime = prettyMs(share.meta.uptimeMs); - json[i].restarts = share.meta.numRestarts || 0; - json[i].peers = share.meta.farmerState.totalPeers || 0; - json[i].contracts = fixContractValue( - share.meta.farmerState.contractCount - ); - json[i].delta = share.meta.farmerState.ntpStatus.delta; - json[i].port = share.meta.farmerState.portStatus.listenPort; - json[i].shared = share.meta.farmerState.spaceUsed; - json[i].sharedPercent = share.meta.farmerState.percentUsed; - } + return json; +} +utils.connectToDaemon(port, function(rpc, sock) { + rpc.status(function(err, shares) { + if (storjshare_status.json) { + // Print out json formatted share statuses + const json = prepareJson(shares); console.log(json); } else { let table = new Table({ diff --git a/lib/api.js b/lib/api.js index 6b95452..1051af0 100644 --- a/lib/api.js +++ b/lib/api.js @@ -99,8 +99,6 @@ class RPC { if (nodeId === null) { return callback(new Error('Invalid Private Key')); } - console.log(config.networkPrivateKey); - console.log(nodeId); const share = this.shares.get(nodeId) || { config: config, From 07e87748540504b97296ed98f91d02ec41c2c71a Mon Sep 17 00:00:00 2001 From: Alexander Leitner Date: Wed, 12 Jul 2017 12:52:02 -0400 Subject: [PATCH 09/13] Don't tunnel by default --- example/farmer.config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/farmer.config.json b/example/farmer.config.json index ed572a7..28cef17 100644 --- a/example/farmer.config.json +++ b/example/farmer.config.json @@ -25,7 +25,7 @@ "rpcPort": 4000, // Enables NAT traversal strategies, first UPnP, then reverse HTTP tunnel // if that fails. Disable if you are public or using dynamic DNS - "doNotTraverseNat": false, + "doNotTraverseNat": true, // Maximum number of tunnels to provide to the network // Tunnels help nodes with restrictive network configurations participate "maxTunnels": 3, From d15b29ac3dd64b1a8ecff1cd5326d112b3d55efe Mon Sep 17 00:00:00 2001 From: Alexander Leitner Date: Wed, 12 Jul 2017 14:17:01 -0400 Subject: [PATCH 10/13] Add maxShardSize option --- example/farmer.config.json | 8 +++++++- lib/api.js | 8 -------- lib/config/farmer.js | 2 +- lib/utils.js | 6 ++++++ test/api.unit.js | 8 ++------ 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/example/farmer.config.json b/example/farmer.config.json index 28cef17..6fae52c 100644 --- a/example/farmer.config.json +++ b/example/farmer.config.json @@ -23,7 +23,10 @@ // Port to bind for RPC server, make sure this is forwarded if behind a // NAT or firewall - otherwise Storj Share will try to punch out "rpcPort": 4000, - // Enables NAT traversal strategies, first UPnP, then reverse HTTP tunnel + // doNotTraverseNat: false requires you to have an external ip address. + // You can use a proxy to gain an external IP address. + // doNotTraverseNat: true Enables NAT traversal strategies + // first UPnP, then reverse HTTP tunnel // if that fails. Disable if you are public or using dynamic DNS "doNotTraverseNat": true, // Maximum number of tunnels to provide to the network @@ -59,6 +62,9 @@ // Amount of space to lease to the network, as human readable string // Valid units are B, KB, MB, GB, TB "storageAllocation": "2GB", + // Max size of shards that will be accepted and stored + // Use this and make this lower if you don't have a strong internet connection + // "maxShardSize": "100MB", // Periodically report your used and free capacity to Storj Labs to improve // the network - no personally identifiable information is sent "enableTelemetryReporting": true diff --git a/lib/api.js b/lib/api.js index 1051af0..c988c17 100644 --- a/lib/api.js +++ b/lib/api.js @@ -118,14 +118,6 @@ class RPC { return callback(new Error(`share ${nodeId} is already running`)); } - if (!share.config.storageAllocation.match(/[0-9]+(T|M|G|K)?B/g)) { - return callback( - new Error('Invalid Storage size specified: '+ - share.config.storageAllocation - ) - ); - } - utils.validateAllocation(share.config, (err) => { if (err) { return callback(new Error(err.message.toLowerCase())); diff --git a/lib/config/farmer.js b/lib/config/farmer.js index 1c5e712..f811755 100644 --- a/lib/config/farmer.js +++ b/lib/config/farmer.js @@ -21,7 +21,7 @@ const config = require('rc')('storjfarmer', { seedList: [], rpcAddress: '127.0.0.1', rpcPort: 4000, - doNotTraverseNat: false, + doNotTraverseNat: true, maxTunnels: 3, maxConnections: 150, tunnelGatewayRange: { diff --git a/lib/utils.js b/lib/utils.js index a7a09de..c151216 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -80,6 +80,12 @@ exports.validate = function(config) { exports.validateAllocation = function(conf, callback) { const self = this; + if (!conf.storageAllocation.match(/[0-9]+([Tt]|[Mm]|[Gg]|[Kk])?[Bb]/g)) { + return callback( + new Error('Invalid storage size specified: '+ conf.storageAllocation) + ); + } + self.getFreeSpace(conf.storagePath, function(err, free) { var allocatedSpace = bytes.parse(conf.storageAllocation); diff --git a/test/api.unit.js b/test/api.unit.js index 41f4099..311594d 100644 --- a/test/api.unit.js +++ b/test/api.unit.js @@ -165,16 +165,12 @@ describe('class:RPC', function() { ) }, './utils': { - validate: sinon.stub(), - validateAllocation: sinon.stub().callsArgWith( - 1, - new Error('Bad space') - ) + validate: sinon.stub() } }); let rpc = new _RPC({ loggerVerbosity: 0 }); rpc.start('path/to/config', function(err) { - expect(err.message).to.equal('Invalid Storage size specified: 23G'); + expect(err.message).to.eql('invalid storage size specified: 23g'); done(); }); }); From 5be7af428cf9faf049a5a2b09979a5d809f74528 Mon Sep 17 00:00:00 2001 From: Alexander Leitner Date: Wed, 12 Jul 2017 14:19:00 -0400 Subject: [PATCH 11/13] Remove deprecated maxOfferConcurrency and offerBackoffLimit --- example/farmer.config.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/example/farmer.config.json b/example/farmer.config.json index 6fae52c..81fd815 100644 --- a/example/farmer.config.json +++ b/example/farmer.config.json @@ -8,8 +8,6 @@ "0f02020202", "0f03020202" ], - // Limits the number of pending OFFER message at one time - "maxOfferConcurrency": 3, // If the seedList is empty, use this bridge to discover seeds // Following a transfer, also send an exchange report to this bridge "bridgeUri": "https://api.storj.io", @@ -45,9 +43,6 @@ "times": 3, "interval": 5000 }, - // Temporarily stop sending OFFER messages if more than this number of shard - // transfers are active - "offerBackoffLimit": 4, // ECDSA private key for your network identity, your Node ID is derived from // this and it is used to sign and verify messages "networkPrivateKey": "", From 7fa178ab4cfafa7ebcab0a7029e0e71eb50a357c Mon Sep 17 00:00:00 2001 From: Alexander Leitner Date: Thu, 13 Jul 2017 16:07:48 -0400 Subject: [PATCH 12/13] Return maxOfferConcurrency, offerBackoffLimit, and doNotTraverseNat for the time being --- example/farmer.config.json | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/example/farmer.config.json b/example/farmer.config.json index 81fd815..6df74d2 100644 --- a/example/farmer.config.json +++ b/example/farmer.config.json @@ -8,6 +8,8 @@ "0f02020202", "0f03020202" ], + // Limits the number of pending OFFER message at one time + "maxOfferConcurrency": 3, // If the seedList is empty, use this bridge to discover seeds // Following a transfer, also send an exchange report to this bridge "bridgeUri": "https://api.storj.io", @@ -21,12 +23,12 @@ // Port to bind for RPC server, make sure this is forwarded if behind a // NAT or firewall - otherwise Storj Share will try to punch out "rpcPort": 4000, - // doNotTraverseNat: false requires you to have an external ip address. + // doNotTraverseNat: true requires you to have an external ip address. // You can use a proxy to gain an external IP address. - // doNotTraverseNat: true Enables NAT traversal strategies + // doNotTraverseNat: false Enables NAT traversal strategies // first UPnP, then reverse HTTP tunnel // if that fails. Disable if you are public or using dynamic DNS - "doNotTraverseNat": true, + "doNotTraverseNat": false, // Maximum number of tunnels to provide to the network // Tunnels help nodes with restrictive network configurations participate "maxTunnels": 3, @@ -43,6 +45,9 @@ "times": 3, "interval": 5000 }, + // Temporarily stop sending OFFER messages if more than this number of shard + // transfers are active + "offerBackoffLimit": 4, // ECDSA private key for your network identity, your Node ID is derived from // this and it is used to sign and verify messages "networkPrivateKey": "", From 1970a81974151ecc2763ba6a00f1bc2bc11d9ddb Mon Sep 17 00:00:00 2001 From: Alexander Leitner Date: Fri, 14 Jul 2017 16:42:59 -0400 Subject: [PATCH 13/13] Add property for offers with data received count --- bin/storjshare-status.js | 3 +++ script/farmer.js | 2 ++ 2 files changed, 5 insertions(+) diff --git a/bin/storjshare-status.js b/bin/storjshare-status.js index aa45c72..14574de 100755 --- a/bin/storjshare-status.js +++ b/bin/storjshare-status.js @@ -82,6 +82,9 @@ function prepareJson(shares) { json[i].contracts = fixContractValue( share.meta.farmerState.contractCount ); + json[i].dataReceivedCount = fixContractValue( + share.meta.farmerState.dataReceivedCount + ); json[i].delta = share.meta.farmerState.ntpStatus.delta; json[i].port = share.meta.farmerState.portStatus.listenPort; json[i].shared = share.meta.farmerState.spaceUsed; diff --git a/script/farmer.js b/script/farmer.js index b3b97e9..19125cc 100755 --- a/script/farmer.js +++ b/script/farmer.js @@ -17,6 +17,7 @@ let farmerState = { totalPeers: 0, lastActivity: Date.now(), contractCount: 0, + dataReceivedCount: 0, portStatus: { listenPort: '...', connectionStatus: -1, @@ -99,6 +100,7 @@ function sendFarmerState() { farmerState.portStatus.connectionStatus = getConnectionStatus(); farmerState.totalPeers = farmer.router.length; farmerState.contractCount = farmer._contractCount || 0; + farmerState.dataReceivedCount = farmer._dataReceivedCount || 0; process.send(farmerState); }