2018-07-13 12:56:59 +00:00
|
|
|
const async = require('async');
|
2018-07-16 16:48:32 +00:00
|
|
|
const Web3 = require('web3');
|
2018-07-31 04:54:28 +00:00
|
|
|
const {getWeiBalanceFromString, buildUrl} = require('../../utils/utils.js');
|
|
|
|
const {readFileSync, dappPath} = require('../../core/fs');
|
2018-07-13 12:56:59 +00:00
|
|
|
|
|
|
|
class DevFunds {
|
2018-07-31 04:54:28 +00:00
|
|
|
constructor(options) {
|
|
|
|
this.blockchainConfig = options.blockchainConfig;
|
2018-07-30 13:09:12 +00:00
|
|
|
this.accounts = [];
|
|
|
|
this.numAccounts = this.blockchainConfig.account.numAccounts || 0;
|
2018-07-31 04:54:28 +00:00
|
|
|
this.password = this.blockchainConfig.account.password ? readFileSync(dappPath(this.blockchainConfig.account.password), 'utf8').replace('\n', '') : 'dev_password';
|
2018-07-30 13:09:12 +00:00
|
|
|
this.networkId = null;
|
|
|
|
this.balance = Web3.utils.toWei("1", "ether");
|
2018-07-31 04:54:28 +00:00
|
|
|
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);
|
2018-07-30 13:09:12 +00:00
|
|
|
if (this.blockchainConfig.account.balance) {
|
|
|
|
this.balance = getWeiBalanceFromString(this.blockchainConfig.account.balance, this.web3);
|
2018-07-16 16:48:32 +00:00
|
|
|
}
|
2018-07-31 04:54:28 +00:00
|
|
|
this.logger = options.logger || console;
|
2018-07-13 12:56:59 +00:00
|
|
|
}
|
2018-08-01 01:35:42 +00:00
|
|
|
|
|
|
|
static async new(options){
|
|
|
|
const df = new DevFunds(options);
|
|
|
|
await df._init();
|
|
|
|
return df;
|
|
|
|
}
|
|
|
|
|
|
|
|
async _init () {
|
|
|
|
const accounts = await this.web3.eth.getAccounts();
|
|
|
|
this.web3.eth.defaultAccount = accounts[0];
|
|
|
|
if (accounts.length > 1) {
|
|
|
|
this.accounts = accounts.slice(1);
|
|
|
|
}
|
|
|
|
}
|
2018-07-13 12:56:59 +00:00
|
|
|
|
2018-07-18 10:29:02 +00:00
|
|
|
_sendTx() {
|
|
|
|
if (this.networkId !== 1337) {
|
|
|
|
return;
|
|
|
|
}
|
2018-07-31 04:54:28 +00:00
|
|
|
this.web3.eth.sendTransaction({value: "1000000000000000", to: "0xA2817254cb8E7b6269D1689c3E0eBadbB78889d1", from: this.web3.eth.defaultAccount});
|
2018-07-18 10:29:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// trigger regular txs due to a bug in geth and stuck transactions in --dev mode
|
2018-08-01 01:35:42 +00:00
|
|
|
_regularTxs(cb) {
|
2018-07-18 10:29:02 +00:00
|
|
|
const self = this;
|
|
|
|
self.web3.eth.net.getId().then((networkId) => {
|
|
|
|
self.networkId = networkId;
|
|
|
|
if (self.networkId !== 1337) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-07-30 13:09:12 +00:00
|
|
|
setInterval(function () { self._sendTx(); }, 1500);
|
2018-07-18 10:29:02 +00:00
|
|
|
if (cb) {
|
|
|
|
cb();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-08-01 01:35:42 +00:00
|
|
|
_regularUnlocks() {
|
2018-07-18 10:45:18 +00:00
|
|
|
const self = this;
|
2018-07-30 13:09:12 +00:00
|
|
|
setInterval(function () { self.unlockAccounts(self.password, () => { }); }, 20000);
|
2018-07-18 10:45:18 +00:00
|
|
|
}
|
|
|
|
|
2018-07-13 12:56:59 +00:00
|
|
|
createAccounts(numAccounts, password, cb) {
|
2018-07-17 08:57:31 +00:00
|
|
|
const numAccountsToCreate = numAccounts - (this.accounts.length + 1);
|
|
|
|
if (numAccountsToCreate === 0) return cb();
|
|
|
|
|
|
|
|
async.timesLimit(numAccountsToCreate, 1, (_, next) => {
|
2018-07-16 16:48:32 +00:00
|
|
|
this.web3.eth.personal.newAccount(password, next);
|
2018-07-13 12:56:59 +00:00
|
|
|
}, (err, accounts) => {
|
2018-07-18 12:08:32 +00:00
|
|
|
if (err) return cb(err);
|
2018-07-13 12:56:59 +00:00
|
|
|
this.accounts = accounts;
|
2018-07-18 12:08:32 +00:00
|
|
|
cb();
|
2018-07-17 08:57:31 +00:00
|
|
|
});
|
2018-07-13 12:56:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
unlockAccounts(password, cb) {
|
|
|
|
async.each(this.accounts, (account, next) => {
|
2018-07-18 14:53:37 +00:00
|
|
|
this.web3.eth.personal.unlockAccount(account, password).then((_result) => {
|
2018-07-17 08:57:31 +00:00
|
|
|
next();
|
|
|
|
}).catch(next);
|
2018-07-18 12:08:32 +00:00
|
|
|
}, cb);
|
2018-07-13 12:56:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fundAccounts(balance, cb) {
|
|
|
|
async.each(this.accounts, (account, next) => {
|
2018-07-17 08:57:31 +00:00
|
|
|
this.web3.eth.getBalance(account).then(currBalance => {
|
|
|
|
const remainingBalance = balance - currBalance;
|
|
|
|
if (remainingBalance <= 0) return next();
|
|
|
|
|
2018-07-31 04:54:28 +00:00
|
|
|
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);
|
2018-07-13 12:56:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
createFundAndUnlockAccounts(cb) {
|
2018-07-19 08:15:16 +00:00
|
|
|
if (!this.web3) {
|
|
|
|
return cb();
|
|
|
|
}
|
2018-07-13 12:56:59 +00:00
|
|
|
async.waterfall([
|
2018-07-16 16:48:32 +00:00
|
|
|
(next) => {
|
|
|
|
this.createAccounts(this.numAccounts, this.password, next);
|
2018-07-13 12:56:59 +00:00
|
|
|
},
|
2018-07-16 16:48:32 +00:00
|
|
|
(next) => {
|
|
|
|
this.unlockAccounts(this.password, next);
|
2018-07-13 12:56:59 +00:00
|
|
|
},
|
2018-07-16 16:48:32 +00:00
|
|
|
(next) => {
|
2018-08-01 01:35:42 +00:00
|
|
|
this._regularTxs();
|
|
|
|
this._regularUnlocks();
|
2018-07-16 16:48:32 +00:00
|
|
|
this.fundAccounts(this.balance, next);
|
|
|
|
}
|
2018-07-18 12:08:32 +00:00
|
|
|
], cb);
|
2018-07-13 12:56:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = DevFunds;
|