Merge pull request #974 from ethereum/ensureTransaction

ES6 class && async/await && wait for tx available
pull/5370/head
yann300 7 years ago committed by GitHub
commit 0483e58fae
  1. 71
      remix-lib/src/execution/txRunner.js
  2. 4
      remix-lib/test/txFormat.js

@ -6,7 +6,8 @@ var BN = ethJSUtil.BN
var executionContext = require('./execution-context') var executionContext = require('./execution-context')
var EventManager = require('../eventManager') var EventManager = require('../eventManager')
function TxRunner (vmaccounts, api) { class TxRunner {
constructor (vmaccounts, api) {
this.event = new EventManager() this.event = new EventManager()
this._api = api this._api = api
this.blockNumber = 0 this.blockNumber = 0
@ -18,13 +19,13 @@ function TxRunner (vmaccounts, api) {
this.pendingTxs = {} this.pendingTxs = {}
this.vmaccounts = vmaccounts this.vmaccounts = vmaccounts
this.queusTxs = [] 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) 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 (gasPrice) tx.gasPrice = executionContext.web3().toHex(gasPrice)
if (api.personalMode()) { if (api.personalMode()) {
promptCb( promptCb(
@ -38,16 +39,27 @@ TxRunner.prototype._executeTx = function (tx, gasPrice, api, promptCb, callback)
} else { } else {
this._sendTransaction(executionContext.web3().eth.sendTransaction, tx, null, callback) 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 self = this
var cb = function (err, resp) { var cb = function (err, resp) {
if (err) { if (err) {
return callback(err, resp) return callback(err, resp)
} }
self.event.trigger('transactionBroadcasted', [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] var args = pass !== null ? [tx, pass, cb] : [tx, cb]
try { try {
@ -55,9 +67,9 @@ TxRunner.prototype._sendTransaction = function (sendTx, tx, pass, callback) {
} catch (e) { } catch (e) {
return callback(`Send transaction failed: ${e.message} . if you use an injected provider, please check it is properly unlocked. `) 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 self = this
var data = args.data var data = args.data
@ -74,9 +86,9 @@ TxRunner.prototype.execute = function (args, confirmationCb, gasEstimationForceS
callback(e, null) 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 const self = this
var account = self.vmaccounts[from] var account = self.vmaccounts[from]
if (!account) { if (!account) {
@ -124,9 +136,9 @@ TxRunner.prototype.runInVm = function (from, to, data, value, gasLimit, useCall,
transactionHash: ethJSUtil.bufferToHex(new Buffer(tx.hash())) 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 const self = this
var tx = { from: from, to: to, data: data, value: value } var tx = { from: from, to: to, data: data, value: value }
@ -177,22 +189,39 @@ TxRunner.prototype.runInNode = function (from, to, data, value, gasLimit, useCal
} }
}) })
}) })
}
} }
function tryTillResponse (txhash, done) { async function tryTillReceiptAvailable (txhash, done) {
executionContext.web3().eth.getTransactionReceipt(txhash, function (err, result) { return new Promise((resolve, reject) => {
if (err || !result) { 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 // 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 { } else {
done(err, { return resolve(receipt)
result: result, }
transactionHash: result ? result.transactionHash : null })
}) })
}
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) { function run (self, tx, stamp, confirmationCb, gasEstimationForceSend, promptCb, callback) {
if (!self.runAsync && Object.keys(self.pendingTxs).length) { if (!self.runAsync && Object.keys(self.pendingTxs).length) {
self.queusTxs.push({ tx, stamp, callback }) self.queusTxs.push({ tx, stamp, callback })

@ -15,7 +15,7 @@ tape('ContractParameters - (TxFormat.buildData) - format input parameters', func
output = JSON.parse(output) output = JSON.parse(output)
var contract = output.contracts['test.sol']['uintContractTest'] var contract = output.contracts['test.sol']['uintContractTest']
context = { output, contract } context = { output, contract }
var bytecode = '608060405234801561001057600080fd5b50610111806100206000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634b521953146044575b600080fd5b348015604f57600080fd5b50609660048036038101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506098565b005b8260008190555081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505600a165627a7a723058209f014353c529016497846216787d1cdca7fe9116c4c1acc2218a45aae9fe6e520029' var bytecode = '608060405234801561001057600080fd5b50610111806100206000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634b521953146044575b600080fd5b348015604f57600080fd5b50609660048036038101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506098565b005b8260008190555081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505600a165627a7a7230582028c4b7d4bd450fb198ccfdf15510df1721e4f8abda2487d4b452c533bed8880b0029'
t.test('(TxFormat.buildData)', function (st) { t.test('(TxFormat.buildData)', function (st) {
st.plan(3) st.plan(3)
testWithInput(st, '123123, "0xf7a10e525d4b168f45f74db1b61f63d3e7619ea8", "34"', bytecode + '000000000000000000000000000000000000000000000000000000000001e0f3000000000000000000000000f7a10e525d4b168f45f74db1b61f63d3e7619ea80000000000000000000000000000000000000000000000000000000000000022') testWithInput(st, '123123, "0xf7a10e525d4b168f45f74db1b61f63d3e7619ea8", "34"', bytecode + '000000000000000000000000000000000000000000000000000000000001e0f3000000000000000000000000f7a10e525d4b168f45f74db1b61f63d3e7619ea80000000000000000000000000000000000000000000000000000000000000022')
@ -96,7 +96,7 @@ function testLinkLibrary2 (st, callbackDeployLibraries) {
'lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2': '0xf7a10e525d4b168f45f74db1b61f63d3e7619e33' 'lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2': '0xf7a10e525d4b168f45f74db1b61f63d3e7619e33'
} }
} }
var data = '608060405234801561001057600080fd5b5061026b806100206000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680636d4ce63c14610046575b600080fd5b34801561005257600080fd5b5061005b61005d565b005b73f7a10e525d4b168f45f74db1b61f63d3e7619e116344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b1580156100bd57600080fd5b505af41580156100d1573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e336344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b15801561013557600080fd5b505af4158015610149573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e336344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b1580156101ad57600080fd5b505af41580156101c1573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e116344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b15801561022557600080fd5b505af4158015610239573d6000803e3d6000fd5b505050505600a165627a7a72305820006fbc873d7822d8c26cfbdfeb92ee52e618dd5d048cfb6c6f7a313ec53dd16d0029' var data = '608060405234801561001057600080fd5b5061026b806100206000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680636d4ce63c14610046575b600080fd5b34801561005257600080fd5b5061005b61005d565b005b73f7a10e525d4b168f45f74db1b61f63d3e7619e116344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b1580156100bd57600080fd5b505af41580156100d1573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e336344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b15801561013557600080fd5b505af4158015610149573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e336344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b1580156101ad57600080fd5b505af41580156101c1573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e116344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b15801561022557600080fd5b505af4158015610239573d6000803e3d6000fd5b505050505600a165627a7a7230582007a22a440570c53944d704e68b3fd4ba3ba4a0fba71c4abd66b195d87f065bcd0029'
var deployMsg = ['creation of library test.sol:lib1 pending...', var deployMsg = ['creation of library test.sol:lib1 pending...',
'creation of library test.sol:lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2 pending...'] 'creation of library test.sol:lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2 pending...']

Loading…
Cancel
Save