lib.rs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. #![cfg_attr(
  2. not(feature = "agave-unstable-api"),
  3. deprecated(
  4. since = "3.1.0",
  5. note = "This crate has been marked for formal inclusion in the Agave Unstable API. From \
  6. v4.0.0 onward, the `agave-unstable-api` crate feature must be specified to \
  7. acknowledge use of an interface that may break without warning."
  8. )
  9. )]
  10. #![no_std]
  11. //! Messages passed between agave and an external pack process.
  12. //! Messages are passed via `shaq::Consumer/Producer`.
  13. //!
  14. //! Memory freeing is responsibility of the external pack process,
  15. //! and is done via `rts-alloc` crate. It is also possible the external
  16. //! pack process allocates memory to pass to agave, BUT it will still be
  17. //! the responsibility of the external pack process to free that memory.
  18. //!
  19. //! Setting up the shared memory allocator and queues is done outside of
  20. //! agave - it can be done by the external pack process or another
  21. //! process. agave will just `join` shared memory regions, but not
  22. //! create them.
  23. //! Similarly, agave will not delete files used for shared memory regions.
  24. //! See `shaq` and `rts-alloc` crates for details.
  25. //!
  26. //! The basic architecture is as follows:
  27. //! โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
  28. //! โ”‚ tpu_to_pack โ”‚ โ”‚ progress_trackerโ”‚
  29. //! โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
  30. //! โ”‚ โ”‚
  31. //! โ”‚ โ”‚
  32. //! โ”‚ โ”‚
  33. //! โ”Œโ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”
  34. //! โ”‚ external scheduler โ”‚
  35. //! โ””โ”€โ–ฒโ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ–ฒโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ฒโ”€โ”€โ”˜
  36. //! โ”‚ โ”‚ โ”‚
  37. //! โ”‚ โ”‚ โ”‚
  38. //! โ”Œโ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ” โ”Œโ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ” ... โ”Œโ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”
  39. //! โ”‚worker1โ”‚ โ”‚worker2 โ”‚ โ”‚workerNโ”‚
  40. //! โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
  41. //!
  42. //! - [`TpuToPackMessage`] are sent from `tpu_to_pack` queue to the
  43. //! external scheduler process. This passes in tpu transactions to be scheduled,
  44. //! and optionally vote transactions.
  45. //! - [`ProgressMessage`] are sent from `progress_tracker` queue to the
  46. //! external scheduler process. This passes information about leader status
  47. //! and slot progress to the external scheduler process.
  48. //! - [`PackToWorkerMessage`] are sent from the external scheduler process
  49. //! to worker threads within agave. This passes a batch of transactions
  50. //! to be processed by the worker threads. This processing can also involve
  51. //! resolving the transactions' addresses, or similar operations beyond
  52. //! execution.
  53. //! - [`WorkerToPackMessage`] are sent from worker threads within agave
  54. //! back to the external scheduler process. This passes back the results
  55. //! of processing the transactions.
  56. //!
  57. /// Reference to a transaction that can shared safely across processes.
  58. #[cfg_attr(
  59. feature = "dev-context-only-utils",
  60. derive(Debug, Clone, Copy, PartialEq, Eq)
  61. )]
  62. #[repr(C)]
  63. pub struct SharableTransactionRegion {
  64. /// Offset within the shared memory allocator.
  65. pub offset: usize,
  66. /// Length of the transaction in bytes.
  67. pub length: u32,
  68. }
  69. /// Reference to an array of Pubkeys that can be shared safely across processes.
  70. #[cfg_attr(
  71. feature = "dev-context-only-utils",
  72. derive(Debug, Clone, Copy, PartialEq, Eq)
  73. )]
  74. #[repr(C)]
  75. pub struct SharablePubkeys {
  76. /// Offset within the shared memory allocator.
  77. pub offset: usize,
  78. /// Number of pubkeys in the array.
  79. /// IF 0, indicates no pubkeys and no allocation needing to be freed.
  80. pub num_pubkeys: u32,
  81. }
  82. /// Reference to an array of [`SharableTransactionRegion`] that can be shared safely
  83. /// across processes.
  84. /// General flow:
  85. /// 1. External pack process allocates memory for
  86. /// `num_transactions` [`SharableTransactionRegion`].
  87. /// 2. External pack sends a [`PackToWorkerMessage`] with `batch`.
  88. /// 3. agave processes the transactions and sends back a [`WorkerToPackMessage`]
  89. /// with the same `batch`.
  90. /// 4. External pack process frees all transaction memory pointed to by the
  91. /// [`SharableTransactionRegion`] in the batch, then frees the memory for
  92. /// the array of [`SharableTransactionRegion`].
  93. #[cfg_attr(feature = "dev-context-only-utils", derive(Debug, PartialEq, Eq))]
  94. #[derive(Clone, Copy)]
  95. #[repr(C)]
  96. pub struct SharableTransactionBatchRegion {
  97. /// Number of transactions in the batch.
  98. pub num_transactions: u8,
  99. /// Offset within the shared memory allocator for the batch of transactions.
  100. /// The transactions are laid out back-to-back in memory as a
  101. /// [`SharableTransactionRegion`] with size `num_transactions`.
  102. pub transactions_offset: usize,
  103. }
  104. /// Reference to an array of response messages.
  105. /// General flow:
  106. /// 1. agave allocates memory for `num_transaction_responses` inner messages.
  107. /// 2. agave sends a [`WorkerToPackMessage`] with `responses`.
  108. /// 3. External pack process processes the inner messages. Potentially freeing
  109. /// any memory within each inner message (see [`worker_message_types`] for details).
  110. #[cfg_attr(
  111. feature = "dev-context-only-utils",
  112. derive(Debug, Clone, Copy, PartialEq, Eq)
  113. )]
  114. #[repr(C)]
  115. pub struct TransactionResponseRegion {
  116. /// Tag indicating the type of message.
  117. /// See [`worker_message_types`] for details.
  118. /// All inner messages/responses per transaction will be of the same type.
  119. pub tag: u8,
  120. /// The number of transactions in the original message.
  121. /// This corresponds to the number of inner response
  122. /// messages that will be pointed to by `response_offset`.
  123. /// This MUST be the same as `batch.num_transactions`.
  124. pub num_transaction_responses: u8,
  125. /// Offset within the shared memory allocator for the array of
  126. /// inner messages.
  127. /// The inner messages are laid out back-to-back in memory starting at
  128. /// this offset. The type of each inner message is indicated by `tag`.
  129. /// There are `num_transaction_responses` inner messages.
  130. /// See [`worker_message_types`] for details on the inner message types.
  131. pub transaction_responses_offset: usize,
  132. }
  133. /// Message: [TPU -> Pack]
  134. /// TPU passes transactions to the external pack process.
  135. /// This is also a transfer of ownership of the transaction:
  136. /// the external pack process is responsible for freeing the memory.
  137. #[cfg_attr(
  138. feature = "dev-context-only-utils",
  139. derive(Debug, Clone, Copy, PartialEq, Eq)
  140. )]
  141. #[repr(C)]
  142. pub struct TpuToPackMessage {
  143. pub transaction: SharableTransactionRegion,
  144. /// See [`tpu_message_flags`] for details.
  145. pub flags: u8,
  146. /// The source address of the transaction.
  147. /// IPv6-mapped IPv4 addresses: `::ffff:a.b.c.d`
  148. /// where a.b.c.d is the IPv4 address.
  149. /// See <https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2>.
  150. pub src_addr: [u8; 16],
  151. }
  152. pub mod tpu_message_flags {
  153. /// No special flags.
  154. pub const NONE: u8 = 0;
  155. /// The transaction is a simple vote transaction.
  156. pub const IS_SIMPLE_VOTE: u8 = 1 << 0;
  157. /// The transaction was forwarded by a validator node.
  158. pub const FORWARDED: u8 = 1 << 1;
  159. /// The transaction was sent from a staked node.
  160. pub const FROM_STAKED_NODE: u8 = 1 << 2;
  161. }
  162. /// Indicates the node is not leader.
  163. pub const IS_NOT_LEADER: u8 = 0;
  164. /// Indicates the node is leader.
  165. pub const IS_LEADER: u8 = 1;
  166. /// Message: [Agave -> Pack]
  167. /// Agave passes leader status to the external pack process.
  168. #[cfg_attr(
  169. feature = "dev-context-only-utils",
  170. derive(Debug, Clone, Copy, PartialEq, Eq)
  171. )]
  172. #[repr(C)]
  173. pub struct ProgressMessage {
  174. /// Indicates if node is currently leader or not.
  175. /// [`IS_LEADER`] if the node is leader.
  176. /// [`IS_NOT_LEADER`] if the node is not leader.
  177. /// Other values should be considered invalid.
  178. pub leader_state: u8,
  179. /// The current slot. This along with a leader schedule is not sufficient
  180. /// for determining if the node is currently leader. There is a slight
  181. /// delay between when a node is supposed to begin its' leader slot, and
  182. /// when a bank is ready for processing transactions as leader.
  183. /// Using [`Self::leader_state`] for determining if the node is leader
  184. /// and has a bank available.
  185. pub current_slot: u64,
  186. /// Next known leader slot or u64::MAX if unknown.
  187. /// This will **not** include the current slot if leader.
  188. /// Node is leader for contiguous slots in the inclusive range
  189. /// [[`Self::next_leader_slot`], [`Self::leader_range_end`]].
  190. pub next_leader_slot: u64,
  191. /// Next known leader slot range end (inclusive) or u64::MAX if unknown.
  192. /// Node is leader for contiguous slots in the inclusive range
  193. /// [[`Self::next_leader_slot`], [`Self::leader_range_end`]].
  194. pub leader_range_end: u64,
  195. /// The remaining cost units allowed to be packed in the block.
  196. /// i.e. block_limit - current_cost_units_used.
  197. /// Only valid if currently leader, otherwise the value is undefined.
  198. pub remaining_cost_units: u64,
  199. /// Progress through the current slot in percentage.
  200. pub current_slot_progress: u8,
  201. }
  202. /// Maximum number of transactions allowed in a [`PackToWorkerMessage`].
  203. /// If the number of transactions exceeds this value, agave will
  204. /// not process the message.
  205. //
  206. // The reason for this constraint is because rts-alloc currently only
  207. // supports up to 4096 byte allocations. We must ensure that the
  208. // `TransactionResponseRegion` is able to contain responses for all
  209. // transactions sent. This is a conservative bound.
  210. pub const MAX_TRANSACTIONS_PER_MESSAGE: usize = 64;
  211. /// Message: [Pack -> Worker]
  212. /// External pack processe passes transactions to worker threads within agave.
  213. ///
  214. /// These messages do not transfer ownership of the transactions.
  215. /// The external pack process is still responsible for freeing the memory.
  216. #[cfg_attr(
  217. feature = "dev-context-only-utils",
  218. derive(Debug, Clone, Copy, PartialEq, Eq)
  219. )]
  220. #[repr(C)]
  221. pub struct PackToWorkerMessage {
  222. /// Flags on how to handle this message.
  223. /// See [`pack_message_flags`] for details.
  224. pub flags: u16,
  225. /// Maximum working bank slot that this message will be processed
  226. /// for. For execution, this will check the leader bank if it exists.
  227. /// If the working bank is ahead of the slot, the return message will
  228. /// be set with [`NOT_PROCESSED`].
  229. pub max_working_slot: u64,
  230. /// Offset and number of transactions in the batch.
  231. /// See [`SharableTransactionBatchRegion`] for details.
  232. /// Agave will return this batch in the response message, it is
  233. /// the responsibility of the external pack process to free the memory
  234. /// ONLY after receiving the response message.
  235. pub batch: SharableTransactionBatchRegion,
  236. }
  237. pub mod pack_message_flags {
  238. //! Flags for [`crate::PackToWorkerMessage::flags`].
  239. //! Use [`CHECK`] or [`EXECUTE`] to specify how a batch should be processed.
  240. //! See [`check_flags`] and [`execution_flags`] for details.
  241. /// Combine with [`check_flags`] for performing checks on transactions.
  242. /// Worker will respond with [`super::worker_message_types::CheckResponse`] if
  243. /// the message is processed.
  244. pub const CHECK: u16 = 0;
  245. /// Combine with additional [`execution_flags`] for executing a batch of transactions.
  246. /// Worker will responsd with [`super::worker_message_types::ExecutionResponse`] if
  247. /// the message is processed.
  248. pub const EXECUTE: u16 = 1;
  249. pub mod execution_flags {
  250. /// Should failing transactions within the batch be dropped (no fee charged & not
  251. /// committed).
  252. pub const DROP_ON_FAILURE: u16 = 1 << 1;
  253. /// If any transaction in the batch is not committed then the entire batch should not be
  254. /// committed.
  255. ///
  256. /// # Note
  257. ///
  258. /// Without `drop_on_failure` this flag will still allow processed but failing transactions
  259. /// to be committed. If both flags are set then any failing transaction will cause all
  260. /// transactions to be aborted.
  261. pub const ALL_OR_NOTHING: u16 = 1 << 2;
  262. }
  263. pub mod check_flags {
  264. /// Transactions should check status: if transaction has already been processed
  265. /// or the nonce is invalid.
  266. pub const STATUS_CHECKS: u16 = 1 << 1;
  267. /// Fee-payer balance should be fetched for transactions.
  268. pub const LOAD_FEE_PAYER_BALANCE: u16 = 1 << 2;
  269. /// Transactions should have ATL pubkeys resolved and returned.
  270. pub const LOAD_ADDRESS_LOOKUP_TABLES: u16 = 1 << 3;
  271. }
  272. }
  273. pub mod processed_codes {
  274. /// The message was processed.
  275. pub const PROCESSED: u8 = 0;
  276. /// The message was not processed because the message was invalid.
  277. pub const INVALID: u8 = 1;
  278. /// The message was not processed because `max_working_slot`
  279. /// was exceeded.
  280. pub const MAX_WORKING_SLOT_EXCEEDED: u8 = 2;
  281. }
  282. /// Message: [Worker -> Pack]
  283. /// Message from worker threads in response to a [`PackToWorkerMessage`].
  284. #[cfg_attr(
  285. feature = "dev-context-only-utils",
  286. derive(Debug, Clone, Copy, PartialEq, Eq)
  287. )]
  288. #[repr(C)]
  289. pub struct WorkerToPackMessage {
  290. /// Offset and number of transactions in the batch.
  291. /// See [`SharableTransactionBatchRegion`] for details.
  292. /// Once the external pack process receives this message,
  293. /// it is responsible for freeing the memory for this batch,
  294. /// and is safe to do so - agave will hold no references to this memory
  295. /// after sending this message.
  296. pub batch: SharableTransactionBatchRegion,
  297. /// See [`processed_codes`] for accepted values.
  298. pub processed_code: u8,
  299. /// Response per transaction in the batch.
  300. /// If message was not processed, this field is undefined.
  301. /// See [`TransactionResponseRegion`] for details.
  302. pub responses: TransactionResponseRegion,
  303. }
  304. pub mod worker_message_types {
  305. use crate::SharablePubkeys;
  306. /// Tag indicating [`ExecutionResponse`] inner message.
  307. pub const EXECUTION_RESPONSE: u8 = 0;
  308. /// Response to pack for a transaction that attempted execution.
  309. /// This response will only be sent if the original message flags
  310. /// requested execution i.e. not [`super::pack_message_flags::RESOLVE`].
  311. #[cfg_attr(
  312. feature = "dev-context-only-utils",
  313. derive(Debug, Clone, Copy, PartialEq, Eq)
  314. )]
  315. #[repr(C)]
  316. pub struct ExecutionResponse {
  317. /// Indicates if the transaction was included in the block or not.
  318. /// If [`not_included_reasons::NONE`], the transaction was included.
  319. pub not_included_reason: u8,
  320. /// If included, cost units used by the transaction.
  321. pub cost_units: u64,
  322. /// If included, the fee-payer balance after execution.
  323. pub fee_payer_balance: u64,
  324. }
  325. pub mod not_included_reasons {
  326. /// The transaction was included in the block.
  327. pub const NONE: u8 = 0;
  328. /// The transaction could not attempt processing because the
  329. /// working bank was unavailable.
  330. pub const BANK_NOT_AVAILABLE: u8 = 1;
  331. /// Transaction dropped because the batch was marked as
  332. /// all_or_nothing and a different transacation failed.
  333. pub const ALL_OR_NOTHING_BATCH_FAILURE: u8 = 3;
  334. // Remaining errors are translations from SDK.
  335. // Moved up to 64 so we have room to add custom reasons in the future.
  336. // Also allows for easy distinguishing between custom scheduling errors
  337. // and sdk errors.
  338. /// An account is already being processed in another transaction in a way
  339. /// that does not support parallelism
  340. pub const ACCOUNT_IN_USE: u8 = 64;
  341. /// A `Pubkey` appears twice in the transaction's `account_keys`. Instructions can reference
  342. /// `Pubkey`s more than once but the message must contain a list with no duplicate keys
  343. pub const ACCOUNT_LOADED_TWICE: u8 = 65;
  344. /// Attempt to debit an account but found no record of a prior credit.
  345. pub const ACCOUNT_NOT_FOUND: u8 = 66;
  346. /// Attempt to load a program that does not exist
  347. pub const PROGRAM_ACCOUNT_NOT_FOUND: u8 = 67;
  348. /// The from `Pubkey` does not have sufficient balance to pay the fee to schedule the transaction
  349. pub const INSUFFICIENT_FUNDS_FOR_FEE: u8 = 68;
  350. /// This account may not be used to pay transaction fees
  351. pub const INVALID_ACCOUNT_FOR_FEE: u8 = 69;
  352. /// The bank has seen this transaction before. This can occur under normal operation
  353. pub const ALREADY_PROCESSED: u8 = 70;
  354. /// The bank has not seen the given `recent_blockhash`
  355. pub const BLOCKHASH_NOT_FOUND: u8 = 71;
  356. /// An error occurred while processing an instruction.
  357. pub const INSTRUCTION_ERROR: u8 = 72;
  358. /// Loader call chain is too deep
  359. pub const CALL_CHAIN_TOO_DEEP: u8 = 73;
  360. /// Transaction requires a fee but has no signature present
  361. pub const MISSING_SIGNATURE_FOR_FEE: u8 = 74;
  362. /// Transaction contains an invalid account reference
  363. pub const INVALID_ACCOUNT_INDEX: u8 = 75;
  364. /// Transaction did not pass signature verification
  365. pub const SIGNATURE_FAILURE: u8 = 76;
  366. /// This program may not be used for executing instructions
  367. pub const INVALID_PROGRAM_FOR_EXECUTION: u8 = 77;
  368. /// Transaction failed to sanitize accounts offsets correctly
  369. pub const SANITIZE_FAILURE: u8 = 78;
  370. pub const CLUSTER_MAINTENANCE: u8 = 79;
  371. /// Transaction processing left an account with an outstanding borrowed reference
  372. pub const ACCOUNT_BORROW_OUTSTANDING: u8 = 80;
  373. /// Transaction would exceed max Block Cost Limit
  374. pub const WOULD_EXCEED_MAX_BLOCK_COST_LIMIT: u8 = 81;
  375. /// Transaction version is unsupported
  376. pub const UNSUPPORTED_VERSION: u8 = 82;
  377. /// Transaction loads a writable account that cannot be written
  378. pub const INVALID_WRITABLE_ACCOUNT: u8 = 83;
  379. /// Transaction would exceed max account limit within the block
  380. pub const WOULD_EXCEED_MAX_ACCOUNT_COST_LIMIT: u8 = 84;
  381. /// Transaction would exceed account data limit within the block
  382. pub const WOULD_EXCEED_ACCOUNT_DATA_BLOCK_LIMIT: u8 = 85;
  383. /// Transaction locked too many accounts
  384. pub const TOO_MANY_ACCOUNT_LOCKS: u8 = 86;
  385. /// Address lookup table not found
  386. pub const ADDRESS_LOOKUP_TABLE_NOT_FOUND: u8 = 87;
  387. /// Attempted to lookup addresses from an account owned by the wrong program
  388. pub const INVALID_ADDRESS_LOOKUP_TABLE_OWNER: u8 = 88;
  389. /// Attempted to lookup addresses from an invalid account
  390. pub const INVALID_ADDRESS_LOOKUP_TABLE_DATA: u8 = 89;
  391. /// Address table lookup uses an invalid index
  392. pub const INVALID_ADDRESS_LOOKUP_TABLE_INDEX: u8 = 90;
  393. /// Transaction leaves an account with a lower balance than rent-exempt minimum
  394. pub const INVALID_RENT_PAYING_ACCOUNT: u8 = 91;
  395. /// Transaction would exceed max Vote Cost Limit
  396. pub const WOULD_EXCEED_MAX_VOTE_COST_LIMIT: u8 = 92;
  397. /// Transaction would exceed total account data limit
  398. pub const WOULD_EXCEED_ACCOUNT_DATA_TOTAL_LIMIT: u8 = 93;
  399. /// Transaction contains a duplicate instruction that is not allowed
  400. pub const DUPLICATE_INSTRUCTION: u8 = 94;
  401. /// Transaction results in an account with insufficient funds for rent
  402. pub const INSUFFICIENT_FUNDS_FOR_RENT: u8 = 95;
  403. /// Transaction exceeded max loaded accounts data size cap
  404. pub const MAX_LOADED_ACCOUNTS_DATA_SIZE_EXCEEDED: u8 = 96;
  405. /// LoadedAccountsDataSizeLimit set for transaction must be greater than 0.
  406. pub const INVALID_LOADED_ACCOUNTS_DATA_SIZE_LIMIT: u8 = 97;
  407. /// Sanitized transaction differed before/after feature activation. Needs to be resanitized.
  408. pub const RESANITIZATION_NEEDED: u8 = 98;
  409. /// Program execution is temporarily restricted on an account.
  410. pub const PROGRAM_EXECUTION_TEMPORARILY_RESTRICTED: u8 = 99;
  411. /// The total balance before the transaction does not equal the total balance after the transaction
  412. pub const UNBALANCED_TRANSACTION: u8 = 100;
  413. /// Program cache hit max limit.
  414. pub const PROGRAM_CACHE_HIT_MAX_LIMIT: u8 = 101;
  415. // This error in agave is only internal, and to avoid updating the sdk
  416. // it is reused for mapping into `ALL_OR_NOTHING_BATCH_FAILURE`.
  417. // /// Commit cancelled internally.
  418. // pub const COMMIT_CANCELLED: u8 = 102;
  419. }
  420. /// Tag indicating [`CheckResponse`] inner message.
  421. pub const CHECK_RESPONSE: u8 = 1;
  422. pub mod parsing_and_sanitization_flags {
  423. /// Flag set if parsing and sanitization failed.
  424. pub const FAILED: u8 = 1 << 0;
  425. }
  426. pub mod status_check_flags {
  427. /// Flag set if status checks were requested.
  428. pub const REQUESTED: u8 = 1 << 0;
  429. /// Flag set if status checks were performed. A previous failure
  430. /// could have caused checks to be skipped.
  431. pub const PERFORMED: u8 = 1 << 1;
  432. /// Flag set if status checks failed due to the transaction being
  433. /// too old.
  434. pub const TOO_OLD: u8 = 1 << 2;
  435. /// Flag set if status checks failed due to the transaction already
  436. /// being processed.
  437. pub const ALREADY_PROCESSED: u8 = 1 << 3;
  438. /// Flag set if status checks failed due to an invalid nonce state.
  439. pub const INVALID_NONCE: u8 = 1 << 4;
  440. }
  441. pub mod fee_payer_balance_flags {
  442. /// Flag set if fee-payer balance was requested.
  443. pub const REQUESTED: u8 = 1 << 0;
  444. /// Flag set if fee-payer balance fetching was performed. A previous
  445. /// failure could have caused balance fetching to be skipped.
  446. pub const PERFORMED: u8 = 1 << 1;
  447. }
  448. pub mod resolve_flags {
  449. /// Flag set if resolving pubkeys was requested.
  450. pub const REQUESTED: u8 = 1 << 0;
  451. /// Flag set if resolving pubkeys was performed.
  452. pub const PERFORMED: u8 = 1 << 1;
  453. /// Flag set if resolving failed.
  454. pub const FAILED: u8 = 1 << 2;
  455. }
  456. #[cfg_attr(
  457. feature = "dev-context-only-utils",
  458. derive(Debug, Clone, Copy, PartialEq, Eq)
  459. )]
  460. #[repr(C)]
  461. pub struct CheckResponse {
  462. /// See [`parsing_and_sanitization_flags`] for details.
  463. pub parsing_and_sanitization_flags: u8,
  464. /// See [`status_check_flags`] for details.
  465. pub status_check_flags: u8,
  466. /// See [`fee_payer_balance_flags`] for details.
  467. pub fee_payer_balance_flags: u8,
  468. /// See [`resolve_flags`] for details.
  469. pub resolve_flags: u8,
  470. /// If [`status_check_flags::ALREADY_PROCESSED`] is set,
  471. /// this is the slot the transaction was previously included in.
  472. /// Otherwise the value is undefined.
  473. pub included_slot: u64,
  474. /// Set only if [`fee_payer_balance_flags::PERFORMED`] is set,
  475. /// otherwise the value is undefined.
  476. /// The slot of the bank used to fetch fee-payer balance.
  477. pub balance_slot: u64,
  478. /// Set only if [`fee_payer_balance_flags::PERFORMED`] is set,
  479. /// otherwise the value is undefined.
  480. /// The balance of the fee-payer.
  481. pub fee_payer_balance: u64,
  482. /// Set only if [`resolve_flags::PERFORMED`] is set,
  483. /// otherwise the value is undefined.
  484. /// The slot of the bank used to resolve the pubkeys.
  485. pub resolution_slot: u64,
  486. /// Set only if [`resolve_flags::PERFORMED`] is set,
  487. /// otherwise the value is undefined.
  488. /// Minimum deactivation slot of any ALT if any.
  489. /// u64::MAX if no ALTs or deactivation.
  490. pub min_alt_deactivation_slot: u64,
  491. /// Set only if [`resolve_flags::PERFORMED`] is set,
  492. /// otherwise the value is undefined.
  493. /// Resolved pubkeys - writable then readonly.
  494. /// Freeing this memory is the responsibility of the external
  495. /// pack process.
  496. pub resolved_pubkeys: SharablePubkeys,
  497. }
  498. }