diff --git a/lib/cmds/blockchain/blockchain.js b/lib/cmds/blockchain/blockchain.js index 9be5a974..6cf02ab4 100644 --- a/lib/cmds/blockchain/blockchain.js +++ b/lib/cmds/blockchain/blockchain.js @@ -170,9 +170,8 @@ Blockchain.prototype.run = function() { if (self.onReadyCallback && !self.readyCalled && data.indexOf('WebSocket endpoint opened') > -1) { if (self.isDev) { self.createFundAndUnlockAccounts((err) => { + // TODO: this is never called! if(err) console.error('Error creating, unlocking, and funding accounts', err); - //self.readyCalled = true; - //self.onReadyCallback(); }); } self.readyCalled = true; @@ -189,7 +188,7 @@ Blockchain.prototype.run = function() { }; Blockchain.prototype.createFundAndUnlockAccounts = function(cb) { - let devFunds = new DevFunds(this.config); + let devFunds = new DevFunds({blockchainConfig: this.config}); devFunds.createFundAndUnlockAccounts((err) => { cb(err); }); diff --git a/lib/cmds/blockchain/dev_funds.js b/lib/cmds/blockchain/dev_funds.js index ae8a524d..6b86533f 100644 --- a/lib/cmds/blockchain/dev_funds.js +++ b/lib/cmds/blockchain/dev_funds.js @@ -1,29 +1,29 @@ const async = require('async'); const Web3 = require('web3'); -const { getWeiBalanceFromString, buildUrl } = require('../../utils/utils.js'); -const { readFileSync, dappPath } = require('../../core/fs'); +const {getWeiBalanceFromString, buildUrl} = require('../../utils/utils.js'); +const {readFileSync, dappPath} = require('../../core/fs'); class DevFunds { - constructor(blockchainConfig, provider, logger) { - this.blockchainConfig = blockchainConfig; + constructor(options) { + this.blockchainConfig = options.blockchainConfig; this.accounts = []; this.numAccounts = this.blockchainConfig.account.numAccounts || 0; - this.password = blockchainConfig.account.password ? readFileSync(dappPath(blockchainConfig.account.password), 'utf8').replace('\n', '') : 'dev_password'; + this.password = this.blockchainConfig.account.password ? readFileSync(dappPath(this.blockchainConfig.account.password), 'utf8').replace('\n', '') : 'dev_password'; this.networkId = null; this.balance = Web3.utils.toWei("1", "ether"); - this.provider = provider || new Web3.providers.WebsocketProvider(buildUrl('ws', this.blockchainConfig.wsHost, this.blockchainConfig.wsPort), { headers: { Origin: "http://localhost:8000" } }); - this.web3 = new Web3(provider); + this.provider = options.provider || new Web3.providers.WebsocketProvider(buildUrl('ws', this.blockchainConfig.wsHost, this.blockchainConfig.wsPort), {headers: {Origin: "http://localhost:8000"}}); + this.web3 = new Web3(this.provider); if (this.blockchainConfig.account.balance) { this.balance = getWeiBalanceFromString(this.blockchainConfig.account.balance, this.web3); } - this.logger = logger || console; + this.logger = options.logger || console; } _sendTx() { if (this.networkId !== 1337) { return; } - this.web3.eth.sendTransaction({ value: "1000000000000000", to: "0xA2817254cb8E7b6269D1689c3E0eBadbB78889d1", from: this.web3.eth.defaultAccount }); + this.web3.eth.sendTransaction({value: "1000000000000000", to: "0xA2817254cb8E7b6269D1689c3E0eBadbB78889d1", from: this.web3.eth.defaultAccount}); } // trigger regular txs due to a bug in geth and stuck transactions in --dev mode @@ -48,7 +48,6 @@ class DevFunds { } getCurrentAccounts(cb) { - this.web3.eth.getAccounts().then((accounts) => { this.web3.eth.defaultAccount = accounts[0]; if (accounts.length > 1) { @@ -80,25 +79,15 @@ class DevFunds { } fundAccounts(balance, cb) { - this.logger.info('[dev_funds]: funding accounts'); async.each(this.accounts, (account, next) => { - this.logger.info('[dev_funds]: funding acct ' + account); this.web3.eth.getBalance(account).then(currBalance => { - this.logger.info('[dev_funds]: acct ' + account + ' current balance ' + currBalance); const remainingBalance = balance - currBalance; if (remainingBalance <= 0) return next(); - this.logger.info('[dev_funds]: funding acct ' + account + ' with ' + remainingBalance); - - this.web3.eth.sendTransaction({ to: account, value: remainingBalance }).then((_result) => { - this.logger.info('[dev_funds]: funding result ' + JSON.stringify(_result)); - next(); - }).catch(next); - }, (err) => { - this.logger.info('[dev_funds]: done funding'); - cb(err); - }); - }); + this.web3.eth.sendTransaction({to: account, value: remainingBalance}).catch(next); + next(); // don't wait for the tx receipt as it never comes! + }).catch(cb); + }, cb); } createFundAndUnlockAccounts(cb) { diff --git a/test/devFunds.js b/test/devFunds.js index f960ea31..1994c00d 100644 --- a/test/devFunds.js +++ b/test/devFunds.js @@ -4,7 +4,6 @@ let TestLogger = require('../lib/tests/test_logger.js'); const Web3 = require('web3'); const i18n = require('../lib/i18n/i18n.js'); const constants = require('../lib/constants.json'); -const Test = require('../lib/tests/test'); const DevFunds = require('../lib/cmds/blockchain/dev_funds'); const async = require('async'); const FakeIpcProvider = require('./helpers/fakeIpcProvider'); @@ -52,73 +51,88 @@ describe('embark.DevFunds', function () { config.rpcPort += constants.blockchain.servicePortOnProxy; } - // TODO put default config - const test = new Test({ loglevel: 'trace' }); + describe('#create, fund, and unlock accounts', function () { + let provider = new FakeIpcProvider(); + let devFunds = new DevFunds({blockchainConfig: config, provider: provider, logger: new TestLogger({})}); + const web3 = new Web3(provider); + it('should create correct number of accounts', function (done) { + provider.injectResult(['0x47d33b27bb249a2dbab4c0612bf9caf4c1950855']); // getAccounts - return --dev account + devFunds.getCurrentAccounts(() => { - test.initWeb3Provider((err) => { - if (err) throw err; - describe('#create, fund, and unlock accounts', function () { - let provider = new FakeIpcProvider(); - let devFunds = new DevFunds(config, provider, new TestLogger({})); - const web3 = new Web3(provider); + provider.injectResult('0x11f4d0a3c12e86b4b5f39b213f7e19d048276dae'); // createAccount #1 + provider.injectResult('0x22f4d0a3c12e86b4b5f39b213f7e19d048276dab'); // createAccount #2 - it('should create correct number of accounts', function (done) { - provider.injectResult(['0x47d33b27bb249a2dbab4c0612bf9caf4c1950855']); // getAccounts - return --dev account - devFunds.getCurrentAccounts(() => { + devFunds.createAccounts(config.account.numAccounts, 'test_password', (err) => { + assert.equal(err, null); - provider.injectResult('0x11f4d0a3c12e86b4b5f39b213f7e19d048276dae'); // createAccount #1 - provider.injectResult('0x22f4d0a3c12e86b4b5f39b213f7e19d048276dab'); // createAccount #2 + // TODO: make FakeIpcProvider smart enough to keep track of created accounts + provider.injectResult(['0x47d33b27bb249a2dbab4c0612bf9caf4c1950855', '0x11f4d0a3c12e86b4b5f39b213f7e19d048276dae', '0x22f4d0a3c12e86b4b5f39b213f7e19d048276dab']); - - devFunds.createAccounts(config.account.numAccounts, 'test_password', (err) => { - assert.equal(err, null); - - provider.injectResult(['0x47d33b27bb249a2dbab4c0612bf9caf4c1950855', '0x11f4d0a3c12e86b4b5f39b213f7e19d048276dae', '0x22f4d0a3c12e86b4b5f39b213f7e19d048276dab']); - web3.eth.getAccounts().then((accts) => { - console.log('got accts: ' + JSON.stringify(accts)); - assert.equal(accts.length, config.account.numAccounts); - assert.strictEqual(accts[0], '0x47D33b27Bb249a2DBab4C0612BF9CaF4C1950855'); - assert.strictEqual(accts[1], '0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe'); - assert.strictEqual(accts[2], '0x22F4d0A3C12E86b4b5F39B213f7e19D048276DAb'); - done(); - }); + web3.eth.getAccounts().then((accts) => { + assert.equal(accts.length, config.account.numAccounts); + assert.strictEqual(accts[0], '0x47D33b27Bb249a2DBab4C0612BF9CaF4C1950855'); + assert.strictEqual(accts[1], '0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe'); + assert.strictEqual(accts[2], '0x22F4d0A3C12E86b4b5F39B213f7e19D048276DAb'); + done(); }); }); }); + }); - it('should fund accounts', function (done) { - console.dir('funding accounts...'); + it('should unlock accounts', function (done) { + provider.injectResult(true); // account #1 unlock result + provider.injectResult(true); // account #2 unlock result - provider.injectResult('1234567890'); // account #1 balance - provider.injectResult('1234567890'); // account #2 balance - provider.injectResult('0xfff12345678976543213456786543212345675432'); // send tx #1 - provider.injectResult('0xfff12345678976543213456786543212345675433'); // send tx #2 + devFunds.unlockAccounts(devFunds.password, (errUnlock) => { + assert.equal(errUnlock, null); + done(); + }); + }); - try { - devFunds.fundAccounts(devFunds.balance, (err) => { - console.dir('accounts funded...'); - assert.equal(err, null); + it('should fund accounts', function (done) { - provider.injectResult(['0x47d33b27bb249a2dbab4c0612bf9caf4c1950855', '0x11f4d0a3c12e86b4b5f39b213f7e19d048276dae', '0x22f4d0a3c12e86b4b5f39b213f7e19d048276dab']); - web3.eth.getAccounts().then((accts) => { - console.log('got accts: ' + JSON.stringify(accts)); + provider.injectResult('1234567890'); // account #1 balance + provider.injectResult('1234567890'); // account #2 balance + // provider.injectResult('0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe'); // send tx #1 + // provider.injectResult('0x22F4d0A3C12E86b4b5F39B213f7e19D048276DAb'); // send tx #2 - const weiFromConfig = utils.getWeiBalanceFromString(config.account.balance); - async.each(accts, (acct, cb) => { - provider.injectResult(web3.utils.numberToHex(weiFromConfig)); - devFunds.web3.eth.getBalance(acct).then((wei) => { - assert.equal(wei, weiFromConfig); - cb(); - }).catch(cb); - }, function(err) { done(); }); - }).catch(() => { - done(); - }); + devFunds.fundAccounts(devFunds.balance, (errFundAccounts) => { + + assert.equal(errFundAccounts, null); + + // inject response for web3.eth.getAccounts + // TODO: make FakeIpcProvider smart enough to keep track of created accounts + provider.injectResult(['0x47d33b27bb249a2dbab4c0612bf9caf4c1950855', '0x11f4d0a3c12e86b4b5f39b213f7e19d048276dae', '0x22f4d0a3c12e86b4b5f39b213f7e19d048276dab']); + + web3.eth.getAccounts().then((accts) => { + + const weiFromConfig = utils.getWeiBalanceFromString(config.account.balance, web3); + + async.each(accts, (acct, cb) => { + + // inject response for web3.eth.getBalance. + // essentially, this will always return the amount we specified + // in the config. + // this is dodgy. really, we should be letting the FakeIpcProvider + // at this point tell us how many wei we have per account (as it would + // in a real node), but the FakeIpcProvider is not smart enough... yet. + // TODO: make FakeIpcProvider smart enough to keep track of balances + provider.injectResult(web3.utils.numberToHex(weiFromConfig)); + + web3.eth.getBalance(acct).then((wei) => { + assert.equal(wei, weiFromConfig); + cb(); + }).catch(cb); + + }, function (errAcctsBalance) { + if (errAcctsBalance) throw errAcctsBalance; + done(); }); - } catch (errFundAccts) { - throw errFundAccts; - } + }).catch((errGetAccts) => { + if (errGetAccts) throw errGetAccts; + done(); + }); }); }); });