0

I'm testing my smart contract on ropsten and I have written an async function that lets me send TRANSACTION transactions from TRANSACTION different accounts. For some reason when TRANSACTION > 20 i get caught in the catch statment with a gas exceeds allowance error and i can't figure out why. I have similarly written a function to fund an arbitrary amount of accounts with eth. Litterally all that is done on the smart contract when invoking instance.methods.addSubmission... is push a uint256 into an array in a mapping(uint256 => uint256[])

async function multipleTx() {
  let accounts = await web3.eth.getAccounts()
  console.log('Issuing Transactions...')
  let totalGasUsed = 0
  const promisesArr = []
  const sendBlockNumber = await web3.eth.getBlockNumber()
  const sendTimeStamp = Date.now()

  for (let i = 0; i < TRANSACTIONS; i++) {
    console.log('account', i, 'is', accounts[i])
    promisesArr.push(
      instance.methods.addSubmissionNoCheck(1, 139).send({
        from: accounts[i],
        gasPrice: 10000000000,
      })
    )
  }
  await Promise.all(promisesArr)
    .then(async (receipts) => {
      let lastBlock = receipts[0].blockNumber
      receipts.forEach((receipt) => {
        totalGasUsed += receipt.gasUsed
        lastBlock =
          receipt.blockNumber > lastBlock ? receipt.blockNumber : lastBlock
      })
      await outputResults(
        sendTimeStamp,
        totalGasUsed,
        sendBlockNumber,
        lastBlock
      )
    })
    .catch((error) => {
      console.log('multipleTX():', error)
    })
}

console output:

multipleTX(): Error: gas required exceeds allowance (8000029) or always failing
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)

smart contract function

mapping(uint256 => uint256[]) public submissions;

function addSubmissionNoCheck(uint256 key, uint256 timeAtLocation) external {
  submissions[key].push(timeAtLocation);
}

Update:

I have removed the gas limit specification as per my own solution below and instead and overfunded the accounts and it seems to work now. I've ran multiple times doing 20 transactions from 20 different accounts. However i feel like if the problem was insufficent funds in the accounts i should receive the Insufficient funds for gas * price + value error.

  • can you post the console output please – Majd TL Apr 21 at 7:35
  • @MajdTL sure!:) – Conviley Apr 21 at 7:36
  • What are you doing in addSubmission? Are you testing in ropsten or a private testnet? (in ropsten case do you have a transaction hash that fails?) The error message says that either a transaction requires more gas than allowed of it reverts. – Ismael Apr 21 at 8:10
  • @Ismael i updated my post to include the smart contract function. Yes i'm testing on ropsten but i get no transaction hash returned to me since i never get inside the then clause. I also manually checked some of the addresses supposedly used in my for loop on etherscan but i find no failed transactions according to etherscan, in fact no new transactions at all so they are not being sent – Conviley Apr 21 at 8:20
  • That's addSubmissionNoCheck, not addSubmission! May I speculate that you have a require statement in the former? – goodvibration Apr 21 at 8:22
0

I seem to have solved my issues by setting a lower gas limit on each of the transactions such that they sum up to a gas limit lower than 8,000,000 GAS which is the gas limit of a block. So for instance, with 20 transactions, i set it to 75000since I saw based on the receipts my tx costs in the worst case my addSubmission function costs 69095. 75000 * 20 < 8,000,000 and it went through.

Why did it work? Thoughts

web3 is calculating the potential gas required by taking gas limit * number of transacting accounts and if this exceeds block gas limit it fails. Now it does work if in the for loop i use the same account then I can fire off 20 transactions without a problem but since i use multiple accounts for whatever reason web3 first caluclates gas limits as if it was separate accounts but then when the promise.All runs it applies the calculated gas such that it's ONE transaction from ONE account and it exceeds the block gas limit and therefore fails. This might be because the walletprovider for the web3 instance uses the same mneumonic? i set it the following way

const walletProvider = new HDWalletProvider(mnemonic, infura.endpoint, 0, 100)
const web3 = new Web3(walletProvider)
| improve this answer | |
  • It doesn't make sense. If there are more transactions than possible to fit in one block it should create more blocks instead of failing. – Ismael Apr 21 at 11:27
  • @Ismael I'm not sure what to say. I showed my friend, who'm I'm working with, the error and he saw the exceeds allowance and he thought maybe it's calculating gas limit * number of accounts and if it exceeds the block gas limit it won't allow me to send the transaction. I thought it did not make sense but we tried and it does work now. So we don't quite understand why it works. I am quite confused.. – Conviley Apr 21 at 11:46
  • Are you testing against ropsten or rinkeby? Do you have a transaction hash of a failed transaction? A related problem, since you are using infura, is that they limit how many request you can send with a free account. – Ismael Apr 21 at 13:43
  • @Ismael Yes this is on ropsten. No i don't have a transaction hash since i get caught in the catch statement so i don't get a tx receipt and I also checked the addresses manually on etherscan and there is no recorded transaction when it fails. Lastly, i am no way near the 100,000requests/day limit. i know this because i still can issue transactions just not the way i mentioned in my original post – Conviley Apr 21 at 13:53
  • The lack of a failed transaction hint the problem is not in the contract but somewhere between your script and the blockchain. Perhaps you exceed some internal limit of node, web3 or infura (perhaps it takes too long to process many transactions). Also 100k req/day is not that much, around 69 req/min. – Ismael Apr 22 at 4:01
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!

| improve this answer | |

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.