|
|
|
@ -6,7 +6,8 @@ var BN = ethJSUtil.BN |
|
|
|
|
var executionContext = require('./execution-context') |
|
|
|
|
var EventManager = require('../eventManager') |
|
|
|
|
|
|
|
|
|
function TxRunner (vmaccounts, api) { |
|
|
|
|
class TxRunner { |
|
|
|
|
constructor (vmaccounts, api) { |
|
|
|
|
this.event = new EventManager() |
|
|
|
|
this._api = api |
|
|
|
|
this.blockNumber = 0 |
|
|
|
@ -18,13 +19,13 @@ function TxRunner (vmaccounts, api) { |
|
|
|
|
this.pendingTxs = {} |
|
|
|
|
this.vmaccounts = vmaccounts |
|
|
|
|
this.queusTxs = [] |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TxRunner.prototype.rawRun = function (args, confirmationCb, gasEstimationForceSend, promptCb, cb) { |
|
|
|
|
rawRun (args, confirmationCb, gasEstimationForceSend, promptCb, cb) { |
|
|
|
|
run(this, args, Date.now(), confirmationCb, gasEstimationForceSend, promptCb, cb) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TxRunner.prototype._executeTx = function (tx, gasPrice, api, promptCb, callback) { |
|
|
|
|
_executeTx (tx, gasPrice, api, promptCb, callback) { |
|
|
|
|
if (gasPrice) tx.gasPrice = executionContext.web3().toHex(gasPrice) |
|
|
|
|
if (api.personalMode()) { |
|
|
|
|
promptCb( |
|
|
|
@ -38,16 +39,29 @@ TxRunner.prototype._executeTx = function (tx, gasPrice, api, promptCb, callback) |
|
|
|
|
} else { |
|
|
|
|
this._sendTransaction(executionContext.web3().eth.sendTransaction, tx, null, callback) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TxRunner.prototype._sendTransaction = function (sendTx, tx, pass, callback) { |
|
|
|
|
_sendTransaction (sendTx, tx, pass, callback) { |
|
|
|
|
var self = this |
|
|
|
|
var cb = function (err, resp) { |
|
|
|
|
if (err) { |
|
|
|
|
return callback(err, resp) |
|
|
|
|
} |
|
|
|
|
self.event.trigger('transactionBroadcasted', [resp]) |
|
|
|
|
tryTillResponse(resp, callback) |
|
|
|
|
|
|
|
|
|
var listenOnResponse = () => { |
|
|
|
|
return new Promise(async (resolve, reject) => { |
|
|
|
|
var result = await tryTillReceiptAvailable(resp) |
|
|
|
|
tx = await tryTillTxAvailable(resp) |
|
|
|
|
resolve({ |
|
|
|
|
result,
|
|
|
|
|
tx, |
|
|
|
|
transactionHash: result ? result.transactionHash : null, |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
listenOnResponse().then((txData) => { callback(null, txData) }).catch((error) => { callback(error) }) |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
var args = pass !== null ? [tx, pass, cb] : [tx, cb] |
|
|
|
|
try { |
|
|
|
@ -55,9 +69,9 @@ TxRunner.prototype._sendTransaction = function (sendTx, tx, pass, callback) { |
|
|
|
|
} catch (e) { |
|
|
|
|
return callback(`Send transaction failed: ${e.message} . if you use an injected provider, please check it is properly unlocked. `) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TxRunner.prototype.execute = function (args, confirmationCb, gasEstimationForceSend, promptCb, callback) { |
|
|
|
|
execute (args, confirmationCb, gasEstimationForceSend, promptCb, callback) { |
|
|
|
|
var self = this |
|
|
|
|
|
|
|
|
|
var data = args.data |
|
|
|
@ -74,9 +88,9 @@ TxRunner.prototype.execute = function (args, confirmationCb, gasEstimationForceS |
|
|
|
|
callback(e, null) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TxRunner.prototype.runInVm = function (from, to, data, value, gasLimit, useCall, callback) { |
|
|
|
|
runInVm (from, to, data, value, gasLimit, useCall, callback) { |
|
|
|
|
const self = this |
|
|
|
|
var account = self.vmaccounts[from] |
|
|
|
|
if (!account) { |
|
|
|
@ -124,9 +138,9 @@ TxRunner.prototype.runInVm = function (from, to, data, value, gasLimit, useCall, |
|
|
|
|
transactionHash: ethJSUtil.bufferToHex(new Buffer(tx.hash())) |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TxRunner.prototype.runInNode = function (from, to, data, value, gasLimit, useCall, confirmCb, gasEstimationForceSend, promptCb, callback) { |
|
|
|
|
runInNode (from, to, data, value, gasLimit, useCall, confirmCb, gasEstimationForceSend, promptCb, callback) { |
|
|
|
|
const self = this |
|
|
|
|
var tx = { from: from, to: to, data: data, value: value } |
|
|
|
|
|
|
|
|
@ -177,22 +191,39 @@ TxRunner.prototype.runInNode = function (from, to, data, value, gasLimit, useCal |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function tryTillResponse (txhash, done) { |
|
|
|
|
executionContext.web3().eth.getTransactionReceipt(txhash, function (err, result) { |
|
|
|
|
if (err || !result) { |
|
|
|
|
async function tryTillReceiptAvailable (txhash, done) { |
|
|
|
|
return new Promise((resolve, reject) => { |
|
|
|
|
executionContext.web3().eth.getTransactionReceipt(txhash, async (err, receipt) => { |
|
|
|
|
if (err || !receipt) { |
|
|
|
|
// Try again with a bit of delay if error or if result still null
|
|
|
|
|
setTimeout(function () { tryTillResponse(txhash, done) }, 500) |
|
|
|
|
await pause() |
|
|
|
|
return resolve(await tryTillReceiptAvailable(txhash)) |
|
|
|
|
} else { |
|
|
|
|
done(err, { |
|
|
|
|
result: result, |
|
|
|
|
transactionHash: result ? result.transactionHash : null |
|
|
|
|
return resolve(receipt) |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async function tryTillTxAvailable (txhash, done) { |
|
|
|
|
return new Promise((resolve, reject) => { |
|
|
|
|
executionContext.web3().eth.getTransaction(txhash, async (err, tx) => { |
|
|
|
|
if (err || !tx) { |
|
|
|
|
// Try again with a bit of delay if error or if result still null
|
|
|
|
|
await pause() |
|
|
|
|
return resolve(await tryTillTxAvailable(txhash)) |
|
|
|
|
} else { |
|
|
|
|
return resolve(tx) |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async function pause () { return new Promise((resolve, reject) => { setTimeout(resolve, 500) }) } |
|
|
|
|
|
|
|
|
|
function run (self, tx, stamp, confirmationCb, gasEstimationForceSend, promptCb, callback) { |
|
|
|
|
if (!self.runAsync && Object.keys(self.pendingTxs).length) { |
|
|
|
|
self.queusTxs.push({ tx, stamp, callback }) |
|
|
|
|