Skip to content
This repository has been archived by the owner on Sep 5, 2020. It is now read-only.

Possibility to specify IPC path & RPC over HTTP support #420

Closed
wants to merge 9 commits into from
8 changes: 4 additions & 4 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const argv = require('yargs')
.usage('Usage: $0 [options]')
.describe('version', 'Display app version')
.describe('mode', 'App mode: wallet, mist (default)')
.describe('rpc', 'RPC endpoint. Can be http URL or IPC socket path')
.describe('gethpath', 'Path to geth executable to use instead of default')
.describe('ethpath', 'Path to eth executable to use instead of default')
.describe('ignore-gpu-blacklist', 'Ignores GPU blacklist (needed for some Linux installations)')
Expand Down Expand Up @@ -51,7 +52,7 @@ global.path = {
global.appName = 'Mist';

global.production = false;

global.rpcUri = argv.rpc;
global.mode = (argv.mode ? argv.mode : 'mist');
global.paths = {
geth: argv.gethpath,
Expand Down Expand Up @@ -348,8 +349,7 @@ app.on('ready', function() {

// START GETH
const checkNodeSync = require('./modules/checkNodeSync.js');
const net = require('net');
const socket = new net.Socket();
const socket = require('./modules/ipc/socket')(ipcPath);
var intervalId = errorTimeout = null;
var count = 0;

Expand Down Expand Up @@ -581,4 +581,4 @@ var startMainWindow = function(appStartWindow){
global.webviews = Tabs.find({},{sort: {position: 1}, fields: {name: 1, _id: 1}}).fetch();
appMenu(global.webviews);
});
};
};
2 changes: 1 addition & 1 deletion modules/ipc/dechunker.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,4 @@ module.exports = function(data, callback){

callback(null, result);
});
};
};
8 changes: 6 additions & 2 deletions modules/ipc/getIpcPath.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@ const log = require('../utils/logger').create('getIpcPath');

module.exports = function() {
var p = require('path');
var path = global.path.HOME;
var providedPath = global.rpcUri;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why you create this variable here? Why not simply if(global.rpcUri) ?

if (providedPath) {
return providedPath;
}

var path = global.path.HOME;
if(process.platform === 'darwin')
path += '/Library/Ethereum/geth.ipc';

Expand All @@ -25,4 +29,4 @@ module.exports = function() {
log.debug('CONNECT to IPC PATH: '+ path);

return path;
};
};
74 changes: 74 additions & 0 deletions modules/ipc/httpCompatSocket.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@

const util = require('util');
const EventEmitter = require('events').EventEmitter;
const http = require('http');

function call(hostname, port, data) {
return new Promise((resolve, reject) => {
console.log(data);
const req = http.request({
hostname: hostname,
port: port,
path: '/',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length
}
}, resolve);

// TODO Not sure why it's needed
// Seems that responses hang somewhere without it
setTimeout(() => {
req.on('error', reject);
req.write(data);
req.end();
}, 50);
});
}

function HttpCompatSocket(hostname, port) {
this.call = call.bind(null, hostname, port);
}

util.inherits(HttpCompatSocket, EventEmitter);

Object.assign(HttpCompatSocket.prototype, {
call: null,
encoding: 'utf8',
writable: true, // socket is always writable

connect(event) {
this.call(JSON.stringify({
jsonrpc: "2.0",
id: 0,
method: "eth_syncing",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better use eth_accounts for that, as eth_syncing is not available in older nodes.

params: []
})).then((res) => {
if (res.statusCode === 200) {
return this.emit('connect');
}
throw 'Unable to connect to HTTP RPC';
}).catch(this.emit.bind(this, 'error'));
return this;
},
write(msg) {
this.call(msg)
.then((res) => {
res.setEncoding(this.encoding);
res.on('data', (chunk) => this.emit('data', chunk));
res.on('end', (chunk) => this.emit('data', chunk || ''));
})
.catch((err) => this.emit('error', err));
},
setEncoding(encoding) {
this.encoding = encoding;
},
setTimeout(timeout) {
},
destroy() {
},
});


module.exports = HttpCompatSocket;
9 changes: 4 additions & 5 deletions modules/ipc/ipcProviderBackend.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ The IPC provider backend filter and tunnel all incoming request to the IPC geth
@module ipcProviderBackend
*/

var dechunker = require('./dechunker.js');
const dechunker = require('./dechunker.js');
const newSocket = require('./socket.js');
const log = require('../utils/logger').create('ipcProviderBackend');

/**
Expand All @@ -18,8 +19,6 @@ global.sockets = {};
module.exports = function(){
const _ = require('underscore');
const ipc = require('electron').ipcMain;
const net = require('net');
const Socket = net.Socket;
const getIpcPath = require('./getIpcPath.js');
const popupWindow = require('../popupWindow.js');

Expand Down Expand Up @@ -68,7 +67,7 @@ module.exports = function(){
@constructor
*/
var GethConnection = function(event) {
this.ipcSocket = new Socket();
this.ipcSocket = newSocket(ipcPath);
this.path = ipcPath;
this.syncEvents = {};
this.asyncEvents = {};
Expand Down Expand Up @@ -593,4 +592,4 @@ module.exports = function(){
ipc.on('ipcProvider-writeSync', function(event, payload){
sendRequest(event, payload, true);
});
};
};
6 changes: 3 additions & 3 deletions modules/ipc/nodeConnector.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

const _ = require('underscore');
const dechunker = require('./dechunker.js');
const newSocket = require('./socket.js');
const log = require('../utils/logger').create('nodeConnector');
const net = require('net');
var idCount = 1;

/**
Expand All @@ -16,7 +16,7 @@ The node connection, is a wrapper for the JSON RPC to execute commands on the no
*/
var NodeConnector = function(ipcPath) {
var _this = this;
this.socket = new net.Socket();
this.socket = newSocket(ipcPath);
this.ipcPath = ipcPath;
this.callbacks = {};

Expand Down Expand Up @@ -75,4 +75,4 @@ NodeConnector.prototype.destroy = function() {



module.exports = NodeConnector;
module.exports = NodeConnector;
16 changes: 16 additions & 0 deletions modules/ipc/socket.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

const net = require('net');
const HttpSocket = require('./httpCompatSocket.js');
const prefix = 'http://';

module.exports = function newSocket(ipcPath) {
if (ipcPath.indexOf(prefix) === 0) {
const path = ipcPath.substr(prefix.length).split(':');
const port = parseInt(path[1], 10);
return new HttpSocket(
path[0] || 'localhost',
isNaN(port) ? 8545 : port
);
}
return new net.Socket();
};