0

I'm having a weird issue with the code below in that sometimes it works and sometimes it doesn't. It seems more apparent when TRANSACTIONS is set to a larger number. I have had it fail AND pass with TRANSACTIONSset to 20. What boggles my mind is that if i set from: to always be accounts[0] it seems to work every time, even when i set TRANSACTIONS to 100. The error is thrown in executePromises() and I show the error below but it's a Error: gas required exceeds allowance (8000029) or always failing transaction-error. Further i have observed that, when it fails, it does send out some transactions that get picked up for example it sent out transactions for account 1-5 but not for the 6th or 7th etc.

Can someone shed some light on this?

async function multipleTx(
  TRANSACTIONS,
  GAS_PRICE,
) {
  let accounts = await web3.eth.getAccounts()
  let tripKey = 0
  var sendBlockNumber = await web3.eth.getBlockNumber()
  let bookingPromiseArr = []
  let txStartTime = Date.now()
  for (let i = 0; i < TRANSACTIONS; i++) {
    let promise = ''
    promise = instance.methods.bookTrip(tripKey).send({
      from: accounts[i],
      gasPrice: GAS_PRICE,
      value: 1,
    })
    bookingPromiseArr.push(promise)
  }
  var receipts = await executePromises(bookingPromiseArr)

  /* more code below ...*/
}

async function executePromises(promisesArr) {
  let res = await Promise.all(promisesArr)
    .then(async (receipts) => {
      return receipts
    })
    .catch((error) => {
      console.log('executePromises():', error)
      process.exit(1)
    })
  return res
}

Smart Contract Function

    function bookTrip(uint256 key) external payable requireTrip(key) {
        Trip storage trip = trips[key];
        trip.passengers[msg.sender] = trip.price;
        trip.passengerCount++;
        emit LogNewTripPassenger(msg.sender, key, trip.price);
    }

Error Log:

executePromises(): Error: gas required exceeds allowance (8000029) or always fai
ling transaction
    at C:\Users\Diddi\Documents\mjukvaruteknik\examensarbete\tqdt33\node_modules
\@truffle\hdwallet-provider\node_modules\web3-provider-engine\subproviders\provi
der.js:18:36
    at XMLHttpRequest.request.onreadystatechange (C:\Users\Diddi\Documents\mjukv
aruteknik\examensarbete\tqdt33\node_modules\web3-providers-http\src\index.js:96:
13)
    at XMLHttpRequestEventTarget.dispatchEvent (C:\Users\Diddi\Documents\mjukvar
uteknik\examensarbete\tqdt33\node_modules\xhr2-cookies\xml-http-request-event-ta
rget.ts:44:13)
    at XMLHttpRequest._setReadyState (C:\Users\Diddi\Documents\mjukvaruteknik\ex
amensarbete\tqdt33\node_modules\xhr2-cookies\xml-http-request.ts:219:8)
    at XMLHttpRequest._onHttpResponseEnd (C:\Users\Diddi\Documents\mjukvarutekni
k\examensarbete\tqdt33\node_modules\xhr2-cookies\xml-http-request.ts:345:8)
    at IncomingMessage.<anonymous> (C:\Users\Diddi\Documents\mjukvaruteknik\exam
ensarbete\tqdt33\node_modules\xhr2-cookies\xml-http-request.ts:311:39)
    at IncomingMessage.emit (events.js:228:7)
    at endReadableNT (_stream_readable.js:1185:12)
    at processTicksAndRejections (internal/process/task_queues.js:81:21)

Update

I took the advice that @LauriPeltonen gave and stripped everything down as much as I could and looked at what @goodvibration suggested regarding mixing synchronous and asynchronous execution in an incorrect manner. I still get the same error. The code below shows Transaction set to 50. On etherscan I can see that my smart contract received 20 of those supposed 50 transactions. However on a second attempt it managed to send all 50.

const web3 = require('./web3.js')
const DeRail = require('../../build/contracts/DeRail.json')
const address = require('../../address.json')
const instance = new web3.eth.Contract(DeRail.abi, address.address, {
  gasPrice: '20000000000',
})

async function multipleTx(TRANSACTIONS = 50, GAS_PRICE = 1000000000) {
  let accounts = await web3.eth.getAccounts()
  let tripKey = 19
  console.log(accounts.length)
  let bookingPromiseArr = []
  for (let i = 0; i < TRANSACTIONS; i++) {
    let promise = instance.methods.bookTrip(tripKey).send({
      from: accounts[i],
      gasPrice: GAS_PRICE,
      value: 1,
    })
    bookingPromiseArr.push(promise)
  }
  var receipts = await executePromises(bookingPromiseArr)
  process.exit(0)
}

async function executePromises(promisesArr) {
  try {
    let res = await Promise.all(promisesArr)
    return res
  } catch (error) {
    console.log('executePromises():', error.message)
    process.exit(1)
  }
}

multipleTx()
14
  • To me, it is pretty obvious that you are trying to execute a function which is permitted only to accounts[0] (probably the contract owner or something similar). Your transaction fails because the function reverts when called with any other account (not because of a gas-related issue, as might be inferred from the error-message). – goodvibration May 6 '20 at 11:28
  • That doesn't make any sense because i've called that function from other accounts than accounts[0]. The requireTrip modifier doesn't restrict the function in any way regarding who is calling it. To clearify it is my smart contract as well. – Conviley May 6 '20 at 11:33
  • What I would do is reduce the complexity until it the failures end and then figure out what caused it. If the failures persist it has something to do with your deployment logic – Lauri Peltonen May 6 '20 at 11:38
  • What is instance? There is no sign of it in your code prior to using it. Is it possibly a different instance for each transaction (or for some of them)? Could there be different implementations of that function, where in some cases your require(msg.sender == someSpecificAddress)? – goodvibration May 6 '20 at 11:40
  • BTW, I believe that in function executePromises, you are mixing synchronous and asynchronous execution in an incorrect manner. Better just use one of them. For example: try {return await Promise.all(promisesArr);} catch (error) {...}. – goodvibration May 6 '20 at 11:44
0

This seem to have been entirely a problem with Infura. I suspect it is in regard to their rate limits. Nevertheless we have now set up our own ethereum node using geth and are able to isssue as many transactions as we want pretty much problem free!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.