BSC Testnet Error: Task timed out after 20.03 seconds

Hello. Trying to test Autotask with Connected Relayer and receive following issue: Task timed out after 20.03 seconds

My steps:

  1. Add relayer for BSC Testnet
  2. Send 0.2 BNB to Relayer Address
  3. Create Autotask
  4. Run manually

:memo:Details

AUTOTASK START
2022-03-28T15:00:24.522Z INFO relayAddress:: 0x776bcf5ac11787882c45ed9d95cf10d18fd96121
2022-03-28T15:00:47.110Z INFO allowance init:: 0
2022-03-28T15:01:07.183Z ERROR Invoke Error {"errorType":"Error","errorMessage":"Error while attempting request: 2022-03-28T15:01:07.179Z 884ef3b6-e1ee-4629-af29-950ae389cf57 Task timed out after 20.03 seconds","stack":["Error: Error while attempting request: 2022-03-28T15:01:07.179Z 884ef3b6-e1ee-4629-af29-950ae389cf57 Task timed out after 20.03 seconds"," at AutotaskRelayer.execute (/opt/nodejs/node_modules/defender-base-client/lib/autotask/index.js:46:19)"," at processTicksAndRejections (internal/process/task_queues.js:97:5)"," at async DefenderRelaySigner.sendTransaction (/opt/nodejs/node_modules/defender-relay-client/lib/ethers/signer.js:83:15)"]}
END RequestId: 28b9f525-794f-4127-8c7c-a242ccb6dbdc
AUTOTASK COMPLETE

:1234: Code to reproduce

const { DefenderRelaySigner, DefenderRelayProvider } = require('defender-relay-client/lib/ethers')
const ethers = require('ethers')

exports.handler = async function(event) {
const provider = new DefenderRelayProvider(event)
const signer = new DefenderRelaySigner(event, provider, { speed: 'fast', validForSeconds: 120 })

const ADDRESS = '0x68409841B5feCb147D0EDfD3EE7F12d5be160433'
const TOKEN = '0x6CdF5bA7e448770294C69a4607e1Dec2963C6fd4'
const MAX_INT = '115792089237316195423570985008687907853269984665640564039457584007913129639935'

const STAKING_ABI = [...] // omitted
const TOKEN_ABI = [...] // omitted

const contract = new ethers.Contract(ADDRESS, STAKING_ABI, signer)
const token = new ethers.Contract(TOKEN, TOKEN_ABI, signer)
const relayAddress = await signer.getAddress()

console.log("relayAddress:: ", relayAddress)
let allowance = await token.allowance(relayAddress, ADDRESS)

console.log("allowance init:: ", allowance.toString()) // doesn't work after this step

if (allowance == 0) {
await token.approve(ADDRESS, MAX_INT, {
gasLimit: '3000000',
from: relayAddress
})
}
allowance = await token.allowance(relayAddress, ADDRESS)
console.log("allowance general:: ", allowance.toString())

await contract.distributeRewards('1', {
gasLimit: '3000000',
from: relayAddress
})
}

1 Like

Hey @Denis_Ponizhan, thanks for reaching out.

Indeed, the Autotask has an execution timeout, which is what you're seeing in this case.
My guess is that the token.approve is waiting to get resolved and it takes some time until it happens, so the Autotask just time out.

I'll suggest you to separate your execution in two steps;

  1. Create an Autotask to send the token.approve(...). Don't await for it, just send it. That transaction will stay in Defender until it gets mined. We take care of repricing and resubmission logic
  2. Setup a sentinel to monitor token.approve calls to the token.approve function
  3. Create another Autotask trigger to then call to distributeRewards
  4. Wire your sentine to the Autotask trigger, so the distributeRewards is called after the token.approve() is confirmed

Hope it helps!

Hi @ernestognw ,

I've encountered the same problem but on Matic Mainnet.
Do you think is it a best practice to just not wait for the transaction?
Because in my case I need to make sure that the transaction goes through for the system to be up and running and configuring a sentinel won't help much as the system halts and need to restart.

Thanks,
Harish Gunjalli

Hey @HarishGunjalli,

I think it depends on your implementation. I wouldn't say best practice or not, but there are constraints within the Autotask (such as the timeout) that has to be taken into consideration.

If you're running a relayer through a dedicated backend with plenty of time to wait for response, then it's okay to wait.

I don't know about the details of your system but indeed there's no way to 100% guarantee tx inclusion before the timeout, but we do our best to make it through. Best for these cases is to setup asynchronous tasks

@ernestognw Is it possible to modify the timeout time? What is it by default?