validity 不是硬连线到交易池的，而是由运行时定义的。 检查有效性的例子：
- 正在检查交易索引(nonce) 是否正确。
- 就绪队列 - 包括可以包含在一个新的待处理块中的交易。 运行时构建FRAME，交易必须遵循准备队列中确定的顺序。
- 未来队列 - 包含可能在未来变得有效的交易。 例如，一个交易可能有一个
验证交易 <a href="https://substrate.dev/rustdocs/v2.0.0/sp_runtime/transaction_validity/struct.
对于FRAME生成的运行时，节点采用基于帐户的系统排序交易。 Every signed transaction needs to contain a nonce, which is incremented by 1 every time a new transaction is made. For example, the first transaction from a new account will have
nonce = 0 and the second transaction will have
nonce = 1.
At minimum, FRAME transactions have a
provides tag of
encode(sender ++ nonce) and a
requires tag of
encode(sender ++ (nonce -1)) if nonce > 1. Transactions do not require anything if
nonce=0. As a result, all transactions coming from a single sender will form a sequence in which they should be included.
Substrate supports multiple
requires tags, so custom runtimes can create alternate dependency (ordering) schemes.
priority in the
ValidTransaction struct determines the ordering of transactions that are in the ready queue. If a node is the next block author, it will order transactions from high to low priority in the next block until it reaches the weight or length limit of the block.
priority defines the linear ordering of a graph in the case of one transaction unlocking multiple dependent transactions. For example, if we have two (or more) transactions that have their dependencies satisfied, then we use
priority to choose the order for them.
For runtimes built with FRAME,
priority is defined as the
fee that the transaction is going to pay. 例如：
- If we receive 2 transactions from different senders (with
nonce=0), we use
priorityto determine which transaction is more important and included in the block first.
- If we receive 2 transactions from the same sender with an identical
nonce, only one transaction can be included on-chain. We use
priorityto choose the transaction with a higher
feeto store in the transaction pool.
Note that the pool does not know about fees, accounts, or signatures - it only deals with the validity of the transaction and the abstract notion of the
provides parameters. 所有其他详细信息都是由运行时通过
- The pool is responsible for ordering the transactions and returning ones that are ready to be included in the block. 就绪队列中的交易被用来构建一个块。
- 交易被执行，状态更改存储在本地内存中。 Transactions from the
readyqueue are also propagated (gossiped) to peers over the network. We use the exact ordering as the pending block since transactions in the front of the queue have a higher priority and are more likely to be successfully executed in the next block.
- 构建的区块被发布到网络。 All other nodes on the network receive and execute the block.
Note that transactions are not removed from the ready queue when blocks are authored, but removed only on block import. This is due to the possibility that a recently-authored block may not make it into the canonical chain.
validate_transaction is called from the runtime, checks for a valid signature and nonce (or output for a UTXO chain) and returns a
validate_transaction checks transactions in isolation, so it will not catch errors like the same output being spent twice.
Although it is possible,
validate_transaction does not check whether calls to pallets will succeed. It is a potential DoS vector since all transactions in the network will be passed into
validate_transaction function should focus on providing the necessary information for the pool to order and prioritize transactions, and quickly reject all transactions that are invalid or outdated. The function will be called frequently, potentially multiple times for the same transaction. It is also possible for
validate_transaction to fail a dependent transaction that would pass
execute_block if it were executed in the correct order.