te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - Blockhash not found when sending transaction - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Blockhash not found when sending transaction - Stack Overflow

programmeradmin4浏览0评论

When sending a transaction using Solana web3, it sometimes shows this error:
Error: failed to send transaction: Transaction simulation failed: Blockhash not found

What is the proper way of dealing with this error other than retrying for x amount of times?
Is there a way to guarantee this issue won't happen when sending transactions?

Here is an example of how I'm sending a transaction:

const web3 = require("@solana/web3.js")
const bs58 = require('bs58')

const publicKey = new web3.PublicKey(new Uint8Array(bs58.decode("BASE_58_PUBLIC_KEY").toJSON().data))
const secretKey = new Uint8Array(bs58.decode("BASE_58_SECRET_KEY").toJSON().data)

const connection = new web3.Connection(
  ";, "finalized",
  {
    mitment: "finalized",
    confirmTransactionInitialTimeout: 30000
  }
)
const transaction = new web3.Transaction().add(
  web3.SystemProgram.transfer({
    fromPubkey: publicKey,
    toPubkey: publicKey,
    lamports: 1
  })
)
web3.sendAndConfirmTransaction(
  connection,
  transaction,
  [{publicKey: publicKey, secretKey: secretKey}],
  {mitment: "finalized"}
)


How can I improve this to avoid the Blockhash not found error?

When sending a transaction using Solana web3, it sometimes shows this error:
Error: failed to send transaction: Transaction simulation failed: Blockhash not found

What is the proper way of dealing with this error other than retrying for x amount of times?
Is there a way to guarantee this issue won't happen when sending transactions?

Here is an example of how I'm sending a transaction:

const web3 = require("@solana/web3.js")
const bs58 = require('bs58')

const publicKey = new web3.PublicKey(new Uint8Array(bs58.decode("BASE_58_PUBLIC_KEY").toJSON().data))
const secretKey = new Uint8Array(bs58.decode("BASE_58_SECRET_KEY").toJSON().data)

const connection = new web3.Connection(
  "https://api.mainnet-beta.solana.", "finalized",
  {
    mitment: "finalized",
    confirmTransactionInitialTimeout: 30000
  }
)
const transaction = new web3.Transaction().add(
  web3.SystemProgram.transfer({
    fromPubkey: publicKey,
    toPubkey: publicKey,
    lamports: 1
  })
)
web3.sendAndConfirmTransaction(
  connection,
  transaction,
  [{publicKey: publicKey, secretKey: secretKey}],
  {mitment: "finalized"}
)


How can I improve this to avoid the Blockhash not found error?

Share Improve this question edited Feb 14, 2023 at 6:26 Yilmaz 49.5k18 gold badges215 silver badges268 bronze badges asked Jan 15, 2022 at 0:40 Brynne HarmonBrynne Harmon 1151 gold badge1 silver badge6 bronze badges 2
  • I ended up doing a retry backoff as I can't think of anything else. Please let me know if there's a better way to do this! – Brynne Harmon Commented Jan 15, 2022 at 3:04
  • 1 Hey, can you post your solution. I have the same error and none of the reference below solve it. Thank you! – Julia Commented Jan 24, 2022 at 23:03
Add a ment  | 

4 Answers 4

Reset to default 4

Retrying is not a bad thing! In some situations, it's actually the preferred way to handle dropped transactions. For example, that means doing:

// assuming you have a transaction named `transaction` already
const blockhashResponse = await connection.getLatestBlockhashAndContext();
const lastValidBlockHeight = blockhashResponse.context.slot + 150;
const rawTransaction = transaction.serialize();
let blockheight = await connection.getBlockHeight();

while (blockheight < lastValidBlockHeight) {
  connection.sendRawTransaction(rawTransaction, {
    skipPreflight: true,
  });
  await sleep(500);
  blockheight = await connection.getBlockHeight();
}

You may like to read through this cookbook entry about retrying transactions: https://solanacookbook./guides/retrying-transactions.html

Specifically, it explains how to implement some retry logic: https://solanacookbook./guides/retrying-transactions.html#customizing-rebroadcast-logic

And what retrying means specifically: https://solanacookbook./guides/retrying-transactions.html#when-to-re-sign-transactions

You can use the maxRetries option: For web3 / Solana native:

web3.sendAndConfirmTransaction(
  connection,
  transaction,
  {
     maxRetries: 5
  }
)

Or for SPL tokens:

const signature = await transfer(
  connection,
  sender,
  senderTokenAccount.address,
  recipientTokenAccount.address,
  sender.publicKey,
  amount,
  [],
  {
    maxRetries: 6,
  }
);

The Strata foundation has a package for solana and it's production grade.

I've used it at production applications.

    const signature = await sendAndConfirmWithRetry(
      connection, 
      tx.serialize(), 
      {
        maxRetries: 5,
        skipPreflight: true
      },
      "processed");

From here

RecentBlockhash is an important value for a transaction. Your transaction will be rejected if you use an expired recent blockhash (after 150 blocks)

solana has block time of 400ms. that means

150 * 400ms = 60 seconds

That is why you need to query and send transaction very fast. otherwise, your transaction will be dropped for good and you will get that error. correct error response should have been "Blockhash expired"

发布评论

评论列表(0)

  1. 暂无评论