diff --git a/lib/cmds/blockchain/miner.js b/lib/cmds/blockchain/miner.js index 6f26ff14d..771b08867 100644 --- a/lib/cmds/blockchain/miner.js +++ b/lib/cmds/blockchain/miner.js @@ -4,6 +4,10 @@ const NetcatClient = require('netcat/client'); const minerStart = 'miner_start'; const minerStop = 'miner_stop'; const getHashRate = 'miner_getHashrate'; +const getCoinbase = 'eth_coinbase'; +const getBalance = 'eth_getBalance'; +const newBlockFilter = 'eth_newBlockFilter'; +const getChanges = 'eth_getFilterChanges'; class GethMiner { constructor() { @@ -40,9 +44,15 @@ class GethMiner { this.client.unixSocket(ipcPath) .enc('utf8') .connect() - .on('data', function(res){ + .on('data', function(response){ + try { + response = JSON.parse(response); + } catch (e) { + console.error(e); + return; + } if (self.callback) { - self.callback(null, res); + self.callback(response.error, response.result); self.callback = null; } }); @@ -52,7 +62,11 @@ class GethMiner { } self.sendCommand(minerStop, () => { - self.fundAccount(function () { + self.fundAccount(function (err) { + if (err) { + console.error(err); + return; + } if (this.config.mine_periodically) self.start_periodic_mining(); if (this.config.mine_pending_txns) self.start_transaction_mining(); }); @@ -60,34 +74,86 @@ class GethMiner { } - sendCommand(method, callback) { + sendCommand(method, params, callback) { + if (typeof params === 'function') { + callback = params; + params = []; + } if (callback) { this.callback = callback; } - this.client.send(JSON.stringify({"jsonrpc": "2.0", "method": method, "params": [], "id": 1})); + this.client.send(JSON.stringify({"jsonrpc": "2.0", "method": method, "params": params || [], "id": 1})); } - fundAccount(cb) { - const self = this; - const accountFunded = function () { - // TODO check https://github.com/ethereum/wiki/wiki/JSON-RPC for APIs - return (eth.getBalance(eth.coinbase) >= self.config.initial_ether); - }; - - if (accountFunded()) { - return cb(); + getCoinbase(callback) { + if (this.coinbase) { + return callback(null, this.coinbase); } - - console.log("== Funding account"); - this.sendCommand(minerStart); - - const blockWatcher = web3.eth.filter("latest").watch(function () { - if (accountFunded()) { - console.log("== Account funded"); - - blockWatcher.stopWatching(); - self.sendCommand(minerStop, cb); + this.sendCommand(getCoinbase, (err, response) => { + if (err) { + return callback(err); } + this.coinbase = response.result; + if (!this.coinbase) { + return callback('Failed getting coinbase account'); + } + callback(null, this.coinbase); + }); + } + + accountFunded(callback) { + const self = this; + self.getCoinbase((err, coinbase) => { + if (err) { + return callback(err); + } + self.sendCommand(getBalance, [coinbase], (err, result) => { + if (err) { + return callback(err); + } + callback(null, result >= self.config.initial_ether); + }); + }); + } + + watchNewBlocks() { + const self = this; + self.sendCommand(newBlockFilter, (err, filterId) => { + if (err) { + console.error(err); + return; + } + const interval = setInterval(() => { + self.sendCommand(getChanges, [filterId], (err, changes) => { + if (!changes || !changes.length) { + return; + } + self.accountFunded((err, funded) => { + if (funded) { + clearTimeout(interval); + self.sendCommand(minerStop); + } + }); + }); + }, 1000); + }); + } + + fundAccount(callback) { + const self = this; + + self.accountFunded((err, funded) => { + if (err) { + return callback(err); + } + if (funded) { + return callback(); + } + + console.log("== Funding account"); + this.sendCommand(minerStart); + + self.watchNewBlocks(); }); } @@ -143,8 +209,8 @@ class GethMiner { start_transaction_mining() { const self = this; web3.eth.filter("pending").watch(function () { - self.sendCommand(getHashRate, (err, response) => { - if (response.result > 0) return; + self.sendCommand(getHashRate, (err, result) => { + if (result > 0) return; console.log("== Pending transactions! Looking for next block..."); self.sendCommand(minerStart);