txManager
This commit is contained in:
parent
6244ed7392
commit
b22311e2c6
@ -2,7 +2,7 @@ const Web3 = require('web3')
|
|||||||
const { Mutex } = require('async-mutex')
|
const { Mutex } = require('async-mutex')
|
||||||
const { GasPriceOracle } = require('gas-price-oracle')
|
const { GasPriceOracle } = require('gas-price-oracle')
|
||||||
const { toWei, toHex, toBN, BN } = require('web3-utils')
|
const { toWei, toHex, toBN, BN } = require('web3-utils')
|
||||||
const promiEvent = require('web3-core-promievent')
|
const PromiEvent = require('web3-core-promievent')
|
||||||
const { sleep, when } = require('./utils')
|
const { sleep, when } = require('./utils')
|
||||||
|
|
||||||
const nonceErrors = [
|
const nonceErrors = [
|
||||||
@ -40,25 +40,24 @@ class TxManager {
|
|||||||
// todo get rid of it
|
// todo get rid of it
|
||||||
async init() {
|
async init() {
|
||||||
this.nonce = await this._web3.eth.getTransactionCount(this.address, 'latest')
|
this.nonce = await this._web3.eth.getTransactionCount(this.address, 'latest')
|
||||||
this.currentBlock = await this._web3.eth.getBlockNumber()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Submits transaction to Ethereum network. Resolves when tx gets enough confirmations.
|
* Submits transaction to Ethereum network. Resolves when tx gets enough confirmations.
|
||||||
* todo: return PromiEvent that emits progress events
|
* Emits progress events.
|
||||||
*
|
*
|
||||||
* @param tx Transaction to send
|
* @param tx Transaction to send
|
||||||
*/
|
*/
|
||||||
submit(tx) {
|
submit(tx) {
|
||||||
const _promiEvent = promiEvent()
|
const promiEvent = PromiEvent()
|
||||||
this._submit(tx, _promiEvent)
|
this._submit(tx, promiEvent.eventEmitter).then(promiEvent.resolve).catch(promiEvent.reject)
|
||||||
return _promiEvent.eventEmitter
|
return promiEvent.eventEmitter
|
||||||
}
|
}
|
||||||
|
|
||||||
async _submit(tx, _promiEvent) {
|
async _submit(tx, emitter) {
|
||||||
const release = await this._mutex.acquire()
|
const release = await this._mutex.acquire()
|
||||||
try {
|
try {
|
||||||
return new Transaction(tx, this).submit(_promiEvent)
|
return new Transaction(tx, emitter, this).submit()
|
||||||
} finally {
|
} finally {
|
||||||
release()
|
release()
|
||||||
}
|
}
|
||||||
@ -66,10 +65,11 @@ class TxManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Transaction {
|
class Transaction {
|
||||||
constructor(tx, manager) {
|
constructor(tx, emitter, manager) {
|
||||||
Object.assign(this, manager)
|
Object.assign(this, manager)
|
||||||
this.manager = manager
|
this.manager = manager
|
||||||
this.tx = tx
|
this.tx = tx
|
||||||
|
this.emitter = emitter
|
||||||
this.retries = 0
|
this.retries = 0
|
||||||
this.hash = null
|
this.hash = null
|
||||||
// store all submitted hashes to catch cases when an old tx is mined
|
// store all submitted hashes to catch cases when an old tx is mined
|
||||||
@ -78,9 +78,9 @@ class Transaction {
|
|||||||
this.hashes = []
|
this.hashes = []
|
||||||
}
|
}
|
||||||
|
|
||||||
async submit(_promiEvent) {
|
async submit() {
|
||||||
await this._prepare()
|
await this._prepare()
|
||||||
await this._send(_promiEvent)
|
return this._send()
|
||||||
}
|
}
|
||||||
|
|
||||||
async _prepare() {
|
async _prepare() {
|
||||||
@ -89,12 +89,12 @@ class Transaction {
|
|||||||
this.tx.nonce = this.nonce
|
this.tx.nonce = this.nonce
|
||||||
}
|
}
|
||||||
|
|
||||||
async _send(_promiEvent) {
|
async _send() {
|
||||||
const signedTx = await this._web3.eth.accounts.signTransaction(this.tx, this._privateKey)
|
const signedTx = await this._web3.eth.accounts.signTransaction(this.tx, this._privateKey)
|
||||||
this.tx.date = Date.now()
|
this.tx.date = Date.now()
|
||||||
this.tx.hash = signedTx.transactionHash
|
this.tx.hash = signedTx.transactionHash
|
||||||
this.hashes.push(this.tx.hash)
|
this.hashes.push(this.tx.hash)
|
||||||
_promiEvent.eventEmitter.emit('transactionHash', signedTx.transactionHash)
|
this.emitter.emit('transactionHash', signedTx.transactionHash)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this._broadcast(signedTx.rawTransaction)
|
await this._broadcast(signedTx.rawTransaction)
|
||||||
@ -121,7 +121,7 @@ class Transaction {
|
|||||||
let currentBlock = await this._web3.eth.getBlockNumber()
|
let currentBlock = await this._web3.eth.getBlockNumber()
|
||||||
let confirmations = currentBlock > receipt.blockNumber ? currentBlock - receipt.blockNumber : 0
|
let confirmations = currentBlock > receipt.blockNumber ? currentBlock - receipt.blockNumber : 0
|
||||||
while (confirmations <= this.config.CONFIRMATIONS) {
|
while (confirmations <= this.config.CONFIRMATIONS) {
|
||||||
_promiEvent.eventEmitter.emit('confirmations', confirmations)
|
this.emitter.emit('confirmations', confirmations)
|
||||||
|
|
||||||
await sleep(this.config.POLL_INTERVAL)
|
await sleep(this.config.POLL_INTERVAL)
|
||||||
receipt = await this._getReceipts()
|
receipt = await this._getReceipts()
|
||||||
@ -134,24 +134,21 @@ class Transaction {
|
|||||||
|
|
||||||
// we could have bumped nonce during execution, so get the latest one + 1
|
// we could have bumped nonce during execution, so get the latest one + 1
|
||||||
this.manager.nonce = this.tx.nonce + 1
|
this.manager.nonce = this.tx.nonce + 1
|
||||||
_promiEvent.resolve(receipt)
|
return receipt
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('_send', e)
|
console.log('_send', e)
|
||||||
await this._handleSendError()
|
await this._handleSendError()
|
||||||
|
|
||||||
// _promiEvent.reject(error) ?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _getReceipts() {
|
async _getReceipts() {
|
||||||
let receipt
|
|
||||||
for (const hash of this.hashes.reverse()) {
|
for (const hash of this.hashes.reverse()) {
|
||||||
receipt = await this._web3.eth.getTransactionReceipt(hash)
|
const receipt = await this._web3.eth.getTransactionReceipt(hash)
|
||||||
if (receipt !== null) {
|
if (receipt) {
|
||||||
return receipt
|
return receipt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return receipt
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,6 +14,7 @@ const tx = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
|
await TxM.init()
|
||||||
const receipt = await TxM.submit(tx)
|
const receipt = await TxM.submit(tx)
|
||||||
.on('transactionHash', (hash) => {
|
.on('transactionHash', (hash) => {
|
||||||
console.log('hash', hash)
|
console.log('hash', hash)
|
||||||
|
Loading…
Reference in New Issue
Block a user