The transaction pool regularly calls the
validate_unsigned function of the
SignedExtension trait to check transaction validity against current state. This trait then gets used to implement custom extensions in
frame_system, which get passed into the runtime as a single type, for example in a typical
runtime/src/lib.rs file we have:
pub type SignedExtra = ( frame_system::CheckNonZeroSender<Runtime>, frame_system::CheckSpecVersion<Runtime>, frame_system::CheckTxVersion<Runtime>, frame_system::CheckGenesis<Runtime>, frame_system::CheckEra<Runtime>, frame_system::CheckNonce<Runtime>, frame_system::CheckWeight<Runtime>, pallet_transaction_payment::ChargeTransactionPayment<Runtime>, );
So, IIUC this then is used to construct all parts of
extra data that a signed call submitted to the runtime expects:
/// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
TaggedTransactionQueue runtime API provides a way to check that a submitted signed transaction is valid, giving the pool to order transaction by priority etc.
From what I understand, this runtime API verifies all the data in
SignedExtra. My question is how?
How does this extra data gets passed into the signed extension and how does the transaction pool know what and where to check in the encoded call?