Skip to main content

如何确认交易Pending的原因

交易 Pending 后,导致转账迟迟无法完成,用户通常会比较茫然,不知所措。此时我们首先需要判断出 Pending 的具体原因,然后才能分情况处理 Pending 的交易。

交易为什么会 Pending ?

Conflux 网络正常情况一秒钟出两个块,一笔交易被成功发出之后应该在几秒到十几秒内,会被打包并执行。 如果交易迟迟不被打包,那大概率是交易在交易池中 Pending 了,需要发送者进行手动干预。

交易被 Pending 在交易池中,根本原因是没有满足交易打包的条件,主要有三种情况:

  1. 交易使用了非连续的 nonce
  2. 交易发送账号的余额不足以支持交易执行
  3. 网络比较拥堵,此时矿工会优先打包 gasPrice 较高的交易,如果某交易的 gasPrice 比其他交易都低,也比新产生的交易低,此时就会一直等待直到网络不繁忙。

非连续的 nonce

Conflux 同以太坊一样,每个账户都有一个 nonce 值, 为该账户发送交易的序列号,或者说 nonce 决定了交易的执行顺序。一个账户发送交易时需要指定 nonce,并且该 nonce 需要从 0 开始递增。交易也是按照 nonce 递增的顺序执行。

举个例子:

  • 一个新创建的账户它的 nonce 为 0
  • 发送第一笔交易指定 nonce 为 0,交易执行后用户的 nonce 变为 1
  • 该账户从 1-10 发送十笔交易,交易执行后,用户的 nonce 变为 11

此时下一笔可执行交易的 nonce 应为 11,但如果此时发送的交易 nonce 为 15, 那这笔交易会一直 pending 在交易池里,直到 nonce 11-14 的交易被执行

余额不够

在区块链世界,交易是用来进行数字货币转账的,而且发送交易还需要给矿工支付手续费,这样才会有人愿意打包并执行你的交易。所以一个账户想要发送一笔交易,那么该账户的余额需要足够支付交易本身的金额加手续费。如果不足以支付则交易就会一直 Pending 在交易池中,直到账户获得足够的余额。

在 Conflux 中,除了支付手续费之外,还需要为存储空间的使用支付费用,具体收费规则为每占用 1k 空间,支付 1CFX。

所以一笔交易所花费的金额计算方式为:value + gasPrice * gas + storageLimit / 1024

如果交易的 to 地址是一个合约,且合约设置了 Sponsor,这时如果交易满足代付条件的话,则交易发送账号余额仅需要足够支付 value 即可。

gasPrice 过低

目前共有区块链的性能都不是很高,在网络比较拥堵的情况下,交易池中会有大量的交易等待被打包,超过矿工的打包速度,这种情况,矿工是按照 gasPrice 从高到底的优先级选取交易并打包。简单来说 gasPrice 越高,打包速度越快

如果一笔交易的 gasPrice 设置的比较低的话,这笔交易就会一直等待其它交易被打包,而 Pending 在交易池中。

目前在 Conflux 主网和测试网建议 gasPrice 为 1GDrip

备注:1GDrip = 1e9 Drip

cfx_getAccountPendingTransactions 方法

Conflux node 有一个 RPC 方法 cfx_getAccountPendingTransactions 可用户获取某账户在交易池中 Pending 的交易列表,数量,及第一笔 Pending 交易的 Pending 原因。

// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"cfx_getAccountPendingTransactions","params":["cfx:aan02vpwvz8crpa1n10j17ufceefptdc2yzkagxk5u"],"id":1}' -H "Content-Type: application/json" localhost:12539

// Response
{
    "jsonrpc": "2.0",
    "result": {
        "firstTxStatus": {
            "pending": "futureNonce"
        },
        "pendingCount": "0x1",
        // Reference transaction example
        "pendingTransactions": [
            {
                "...": "..."
            }
        ]
    },
    "id": "15922956697249514502"
}

firstTxStatus 字段即是第一笔 Pending 交易的 Pending 原因,有三种可能:

  • pending: futureNonce 表示使用了非连续的 nonce
  • pending: notEnoughCash 表示发送账号余额不足以支持交易执行
  • ready 表示交易本身已满足打包条件,如果交易长期处于此状态,大概率是因为 gasPrice 设置比较小的原因。

说明:该方法只能返回访问的 RPC 节点交易池中的 Pending 交易,由于交易广播延迟的原因,可能发送了交易,且迟迟没有执行,但通过该方法获取不到 Pending 交易。另外交易池本身有 GC 机制,在交易池满之后,会把一些不满足执行条件的交易 GC 掉,此时通过该方法也获取不到 Pending 交易。

如果通过 cfx_getAccountPendingTransactions 方法获取不到 Pending 交易,或通过 cfx_getTransactionByHash 也获取不到交易,这种情况可直接尝试重新发送交易。

使用 ConfluxScan 查看 Pending 交易

ConfluxScan 的账户详情页,有一个 tab 可用于查看该用户的 Pending 交易列表

scan-pending-entry.jpeg

点击之后,如果账户有 Pending 交易,可看到 Pending 列表及第一条 Pending 的原因:

scan-pending-tx-list.jpeg

页面显示原因有三种(同上一节三种一一对应):

  • Wrong nonce
  • Insufficient balance
  • Ready to pack

Scan 该页面其实是通过 cfx_getAccountPendingTransactions 方法获取的 Pending 信息。

使用 Pending 小工具查看原因

Conflux 社区用户也开发一个 Pending TX 查看小工具,可用于查看某账户的 Pending 交易信息

Screen Shot 2022-06-15 at 10.59.02.png

该工具会给出 Pending 的数量,第一笔 Pending 交易的原因及 hash,另外还给出了可能的解决建议

自行分析 Pending 原因

由于交易广播延迟,或发送交易的 RPC 节点与 Scan 所使用 RPC 节点不同原因,可能在 Scan 的账户 Pending 页面,查看不到 Pending 交易列表。此时可自行使用交易 hash 调用 getTransactionByHash 方法查询交易信息,如果能获取到交易,且交易处于 pending 状态(无 blockHash)此时可根据交易的信息(value, gas, gasPrice, storageLimit)以及账户的状态(balance, nonce)判断交易 Pending 的具体原因。

如果 getTransactionByHash 获取不到交易信息,可直接重新发送交易.