Rpc error while sending transactions

      const sig1 = await signTransaction(tx1, buildBasicAccountSigner(signingKey))
      const sig2 = await signTransaction(tx2, buildBasicAccountSigner(signingKey))

      await client.sendAccountTransaction(tx1, sig1)

      const tx1Hash = getAccountTransactionHash(tx1, sig1)
      const tx1Finalization = await client.waitForTransactionFinalization(tx1Hash)

      if ((tx1Finalization.summary as { transactionType: string }).transactionType === "failed") {
        throw new Error("service transaction was rejected by the node")
      }

      await client.sendAccountTransaction(tx2, sig2)
      const tx2Hash = getAccountTransactionHash(tx2, sig2)
      const tx2Finalization = await client.waitForTransactionFinalization(tx2Hash)

      if ((tx2Finalization.summary as { transactionType: string }).transactionType === "failed") {
        throw new Error("payout Transaction was rejected by the node")

I need to send two transaction one after each other, the transactions are created by increment the nonce fetched from the explorer.
I’m encountering some problems:

  • some times i get an rpc error transaction not found
  • some times waitForTransactionFinalization remains pending for ~5 minutes.

Am i doing something wrong? Isn’t It necessary to wait for transactions finalizations?

The source of the problem is likely in the place where you are constructing transactions. What expiry time are you setting? Are you 100% sure the nonces are correct?

Which of the waitForTransactionFinalization is pending for 5min?

Can you simplify your code to a complete example that does not work?

  • I’m setting an expiry for each transaction to Date.now() + 1 hour
  • I don’t think that the nonces are wrong
  • The last one of the two remains pending

  const signingKey = ConcordiumHdWallet.fromHex(seedAsHex, network)
    .getAccountSigningKey(3, 3, 0)
    .toString("hex")

 const { nonce } = await client.getNextAccountNonce(new AccountAddress(address))

  const tx1: AccountTransaction = {
    type: AccountTransactionType.Transfer,
    header: {
      sender: new AccountAddress(address),
      nonce,
      expiry: new TransactionExpiry(new Date(Date.now() + (1000 * 60 * 60)))
    },
    payload: {
      toAddress: new AccountAddress(address1),
      amount: new CcdAmount(amount1)
    }
  }

  const tx2: AccountTransaction = {
    type: AccountTransactionType.Transfer,
    header: {
      sender: new AccountAddress(address),
      nonce: nonce + 1n,
      expiry: new TransactionExpiry(new Date(Date.now() + (1000 * 60 * 60)))
    },
    payload: {
      toAddress: new AccountAddress(address2),
      amount: new CcdAmount(amount2)
    }
  }

const sig1 = await signTransaction(tx1, buildBasicAccountSigner(signingKey))
const sig2 = await signTransaction(tx2, buildBasicAccountSigner(signingKey))

await client.sendAccountTransaction(tx1, sig1)

const tx1Hash = getAccountTransactionHash(tx1, sig1)
const tx1Finalization = await client.waitForTransactionFinalization(tx1Hash)

if ((tx1Finalization.summary as { transactionType: string }).transactionType === "failed") {
  throw new Error("service transaction was rejected by the node")
}

await client.sendAccountTransaction(tx2, sig2)
const tx2Hash = getAccountTransactionHash(tx2, sig2)
const tx2Finalization = await client.waitForTransactionFinalization(tx2Hash)

if ((tx2Finalization.summary as { transactionType: string }).transactionType === "failed") {
  throw new Error("payout Transaction was rejected by the node")

This code sometimes works, but some other times remains stuck

I can’t see anything wrong here. Have you tried looking up the transaction hashes of submitted transactions with, e.g., concordium-client?

I agree that if the nonce was wrong or the transaction was expired I would expect sendAccountTransaction to raise an error.

@soerenbz Do you see anything amiss in the above?

One thing I notice is, there is no reason to compute the transaction hash (getTransactionHash), as this is returned from client.sendTransaction. It shouldn’t make a difference in terms of correctness, obviously, but I would still recommend doing this.

Ok i’ll remove the useless call.
Maybe I should also try to truncate the network call to waitForTransactionFinalization if it remain pending for too long, can you suggest a way to do that?

client.waitForTransactionFinalization takes an optional timeout parameter you can use for this, if I understand you correctly.