@ -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 = functio n ( 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 = fun ction ( 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 } )