Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 42 additions & 9 deletions nanowallet/src/app/services/nodes.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,29 @@ class Nodes {
this._$timeout = $timeout;

nem.model.nodes.testnet = [{
uri: 'http://hugetestalice.nem.ninja'
uri: 'http://libertalia.nemtest.net'
}, {
uri: 'http://hugetestalice2.nem.ninja'
uri: 'http://ocracoke.nemtest.net'
}, {
uri: 'http://medalice2.nem.ninja'
uri: 'http://tortuga.nemtest.net'
}, {
uri: 'http://ntn1.dusanjp.com'
}, {
uri: 'http://localhost'
}];

nem.model.nodes.mainnet = [{
uri: 'http://portobelo.nemmain.net'
}, {
uri: 'http://hugealice.nem.ninja'
}, {
uri: 'http://hugealice2.nem.ninja'
}, {
uri: 'http://hugealice3.nem.ninja'
}, {
uri: 'http://1n.dusanjp.com'
}, {
uri: 'http://2n.dusanjp.com'
}, {
uri: 'http://localhost'
}];
Expand All @@ -178,31 +196,46 @@ class Nodes {
return;
}

/**
* Pick a random node uri in a list of nodes
* Local nodes are skipped, they must be selected explicitly by the user
*
* @param {array} nodes - An array of node objects
*
* @return {string} - A node uri
*/
getRandomNodeUri(nodes) {
let pool = nodes.filter((node) => node.uri !== 'http://localhost');
if (!pool.length) pool = nodes;
return pool[Math.floor(Math.random() * pool.length)].uri;
}

/**
* Check if nodes present in local storage or set default according to network
* If no node in local storage a random node is used, to balance the load between nodes
*/
setDefault() {
if (this._Wallet.network == nem.model.network.data.mainnet.id) {
if (this._storage.selectedMainnetNode) {
this._Wallet.node = this._storage.selectedMainnetNode;
} else {
let endpoint = nem.model.objects.create("endpoint")(nem.model.nodes.mainnet[0].uri, nem.model.nodes.defaultPort);
let endpoint = nem.model.objects.create("endpoint")(this.getRandomNodeUri(nem.model.nodes.mainnet), nem.model.nodes.defaultPort);
this._Wallet.node = endpoint;
}
this._Wallet.nodes = nem.model.nodes.mainnet;
} else if (this._Wallet.network == nem.model.network.data.testnet.id) {
if (this._storage.selectedTestnetNode) {
this._Wallet.node = this._storage.selectedTestnetNode;
} else {
let endpoint = nem.model.objects.create("endpoint")("http://hugetestalice.nem.ninja", nem.model.nodes.defaultPort);
let endpoint = nem.model.objects.create("endpoint")(this.getRandomNodeUri(nem.model.nodes.testnet), nem.model.nodes.defaultPort);
this._Wallet.node = endpoint;
}
this._Wallet.nodes = nem.model.nodes.testnet;
} else {
if (this._storage.selectedMijinNode) {
this._Wallet.node = this._storage.selectedMijinNode;
} else {
let endpoint = nem.model.objects.create("endpoint")(nem.model.nodes.mijin[0].uri, nem.model.nodes.mijinPort);
let endpoint = nem.model.objects.create("endpoint")(this.getRandomNodeUri(nem.model.nodes.mijin), nem.model.nodes.mijinPort);
this._Wallet.node = endpoint;
}
this._Wallet.nodes = nem.model.nodes.mijin;
Expand All @@ -220,13 +253,13 @@ class Nodes {
let _endpoint;
// Set node in local storage according to network
if (this._Wallet.network == nem.model.network.data.mainnet.id) {
_endpoint = endpoint || nem.model.objects.create("endpoint")(nem.model.nodes.mainnet[Math.floor(Math.random()*nem.model.nodes.mainnet.length)].uri, nem.model.nodes.defaultPort);
_endpoint = endpoint || nem.model.objects.create("endpoint")(this.getRandomNodeUri(nem.model.nodes.mainnet), nem.model.nodes.defaultPort);
this._storage.selectedMainnetNode = _endpoint;
} else if (this._Wallet.network == nem.model.network.data.testnet.id) {
_endpoint = endpoint || nem.model.objects.create("endpoint")(nem.model.nodes.testnet[Math.floor(Math.random()*nem.model.nodes.testnet.length)].uri, nem.model.nodes.defaultPort);
_endpoint = endpoint || nem.model.objects.create("endpoint")(this.getRandomNodeUri(nem.model.nodes.testnet), nem.model.nodes.defaultPort);
this._storage.selectedTestnetNode = _endpoint;
} else {
_endpoint = endpoint || nem.model.objects.create("endpoint")(nem.model.nodes.mijin[Math.floor(Math.random()*nem.model.nodes.mijin.length)].uri, nem.model.nodes.mijinPort);
_endpoint = endpoint || nem.model.objects.create("endpoint")(this.getRandomNodeUri(nem.model.nodes.mijin), nem.model.nodes.mijinPort);
this._storage.selectedMijinNode = _endpoint;
}
// Set endpoint in Wallet service
Expand Down
2 changes: 1 addition & 1 deletion nanowallet/tests/specs/importanceTransferModule.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ describe('Importance transfer module tests', function() {
expect(ctrl.customHarvestingNode).toEqual("");
expect(ctrl.harvestingNode).toEqual(Wallet.node);
expect(ctrl.hasFreeSlots).toBe(false);
expect(ctrl.nodes[0]).toEqual(nem.model.objects.create("endpoint")("http://hugetestalice.nem.ninja", 7890));
expect(ctrl.nodes[0]).toEqual(nem.model.objects.create("endpoint")(Wallet.nodes[0].uri, 7890));
expect(ctrl.showSupernodes).toBe(false);
});

Expand Down
92 changes: 85 additions & 7 deletions nanowallet/tests/specs/nodes.service.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,75 @@ describe('Nodes Service', () => {
it('sets a fixed testnet node list on nem.model.nodes', () => {
// Assert:
expect(nem.model.nodes.testnet).toEqual([
{ uri: 'http://hugetestalice.nem.ninja' },
{ uri: 'http://hugetestalice2.nem.ninja' },
{ uri: 'http://medalice2.nem.ninja' },
{ uri: 'http://libertalia.nemtest.net' },
{ uri: 'http://ocracoke.nemtest.net' },
{ uri: 'http://tortuga.nemtest.net' },
{ uri: 'http://ntn1.dusanjp.com' },
{ uri: 'http://localhost' }
]);
});

it('sets a fixed mainnet node list on nem.model.nodes', () => {
// Assert:
expect(nem.model.nodes.mainnet).toEqual([
{ uri: 'http://portobelo.nemmain.net' },
{ uri: 'http://hugealice.nem.ninja' },
{ uri: 'http://hugealice2.nem.ninja' },
{ uri: 'http://hugealice3.nem.ninja' },
{ uri: 'http://1n.dusanjp.com' },
{ uri: 'http://2n.dusanjp.com' },
{ uri: 'http://localhost' }
]);
});
});

describe('getRandomNodeUri', () => {
it('returns a node of the given list', () => {
// Arrange:
const nodes = [{ uri: 'http://node1' }, { uri: 'http://node2' }, { uri: 'http://node3' }];

// Act:
const result = nodesService.getRandomNodeUri(nodes);

// Assert:
expect(nodes).toContain({ uri: result });
});

it('can pick any node of the given list', () => {
// Arrange:
const nodes = [{ uri: 'http://node1' }, { uri: 'http://node2' }, { uri: 'http://node3' }];
const randoms = [0, 0.4, 0.9];
let index = 0;
spyOn(Math, 'random').and.callFake(() => randoms[index++]);

// Act:
const result = randoms.map(() => nodesService.getRandomNodeUri(nodes));

// Assert:
expect(result).toEqual(['http://node1', 'http://node2', 'http://node3']);
});

it('never picks the local node when other nodes are available', () => {
// Arrange:
const nodes = [{ uri: 'http://node1' }, { uri: 'http://localhost' }];
const randoms = [0, 0.5, 0.99];
let index = 0;
spyOn(Math, 'random').and.callFake(() => randoms[index++]);

// Act:
const result = randoms.map(() => nodesService.getRandomNodeUri(nodes));

// Assert:
expect(result).toEqual(['http://node1', 'http://node1', 'http://node1']);
});

it('picks the local node when it is the only one available', () => {
// Act:
const result = nodesService.getRandomNodeUri([{ uri: 'http://localhost' }]);

// Assert:
expect(result).toEqual('http://localhost');
});
});

describe('cleanEndpoint', () => {
Expand Down Expand Up @@ -105,19 +168,33 @@ describe('Nodes Service', () => {
expect(mockWallet.nodes).toBe(nem.model.nodes.mainnet);
});

it('falls back to the first bundled testnet node when nothing is stored', () => {
it('falls back to a random bundled testnet node when nothing is stored', () => {
// Arrange:
mockWallet.network = TESTNET_NETWORK;

// Act:
nodesService.setDefault();

// Assert:
expect(mockWallet.node).toEqual(
nem.model.objects.create('endpoint')('http://hugetestalice.nem.ninja', nem.model.nodes.defaultPort)
);
expect(nem.model.nodes.testnet).toContain({ uri: mockWallet.node.host });
expect(mockWallet.node.host).not.toEqual('http://localhost');
expect(mockWallet.node.port).toEqual(nem.model.nodes.defaultPort);
expect(mockWallet.nodes).toBe(nem.model.nodes.testnet);
});

it('falls back to a random bundled mainnet node when nothing is stored', () => {
// Arrange:
mockWallet.network = MAINNET_NETWORK;

// Act:
nodesService.setDefault();

// Assert:
expect(nem.model.nodes.mainnet).toContain({ uri: mockWallet.node.host });
expect(mockWallet.node.host).not.toEqual('http://localhost');
expect(mockWallet.node.port).toEqual(nem.model.nodes.defaultPort);
expect(mockWallet.nodes).toBe(nem.model.nodes.mainnet);
});
});

describe('update', () => {
Expand All @@ -143,6 +220,7 @@ describe('Nodes Service', () => {

// Assert:
expect(nem.model.nodes.mainnet).toContain({ uri: mockWallet.node.host });
expect(mockWallet.node.host).not.toEqual('http://localhost');
expect(mockStorage.selectedMainnetNode).toBe(mockWallet.node);
});
});
Expand Down
95 changes: 15 additions & 80 deletions nanowallet/tests/test/importanceTransferModuleTests.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
import nem from 'nem-sdk';
import WalletFixture from '../data/wallet';
import AccountDataFixture from '../data/accountData';

/**
* Map the node list of the Wallet service to the endpoint objects exposed by the controllers
*
* @param {object} Wallet - The Wallet service
*
* @return {array} - An array of endpoint objects
*/
const expectedEndpoints = (Wallet) => Wallet.nodes.map((node) => ({
"host": node.uri,
"port": nem.model.nodes.defaultPort
}));

export const setupMainnetWallet = (Wallet, Nodes, DataBridge) => {
Wallet.use(WalletFixture.mainnetWallet);
Nodes.setDefault();
Expand All @@ -25,24 +38,7 @@ export const assertTestnetNodes = ($controller, $rootScope, controlName, Wallet,
ctrl.setNodes();

// Assert:
expect(ctrl.nodes).toEqual([
{
"host": "http://hugetestalice.nem.ninja",
"port": 7890
},
{
"host": "http://hugetestalice2.nem.ninja",
"port": 7890
},
{
"host": "http://medalice2.nem.ninja",
"port": 7890
},
{
"host": "http://localhost",
"port": 7890
}
]);
expect(ctrl.nodes).toEqual(expectedEndpoints(Wallet));
}

export const assertSuperNodes = async ($controller, $rootScope, controlName, Wallet, Nodes, DataBridge, SuperNodeProgram, $timeout) => {
Expand Down Expand Up @@ -83,66 +79,5 @@ export const assertMainnetNodes = async ($controller, $rootScope, controlName, W
$timeout.flush();

// Assert:
expect(ctrl.nodes).toEqual([
{
"host": "http://hugealice.nem.ninja",
"port": 7890
},
{
"host": "http://hugealice2.nem.ninja",
"port": 7890
},
{
"host": "http://hugealice3.nem.ninja",
"port": 7890
},
{
"host": "http://hugealice4.nem.ninja",
"port": 7890
},
{
"host": "http://bigalice3.nem.ninja",
"port": 7890
},
{
"host": "http://san.nem.ninja",
"port": 7890
},
{
"host": "http://go.nem.ninja",
"port": 7890
},
{
"host": "http://hachi.nem.ninja",
"port": 7890
},
{
"host": "http://jusan.nem.ninja",
"port": 7890
},
{
"host": "http://nijuichi.nem.ninja",
"port": 7890
},
{
"host": "http://alice5.nem.ninja",
"port": 7890
},
{
"host": "http://alice6.nem.ninja",
"port": 7890
},
{
"host": "http://alice7.nem.ninja",
"port": 7890
},
{
"host": "http://alice8.nem.ninja",
"port": 7890
},
{
"host": "http://localhost",
"port": 7890
}
]);
expect(ctrl.nodes).toEqual(expectedEndpoints(Wallet));
}