address_lookup_table.rs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. use {
  2. solana_cli::{
  3. address_lookup_table::{
  4. AddressLookupTableCliCommand, DEACTIVATE_LOOKUP_TABLE_WARNING,
  5. FREEZE_LOOKUP_TABLE_WARNING,
  6. },
  7. cli::{process_command, CliCommand, CliConfig},
  8. },
  9. solana_cli_output::{CliAddressLookupTable, CliAddressLookupTableCreated, OutputFormat},
  10. solana_faucet::faucet::run_local_faucet_with_unique_port_for_tests,
  11. solana_keypair::Keypair,
  12. solana_native_token::LAMPORTS_PER_SOL,
  13. solana_net_utils::SocketAddrSpace,
  14. solana_pubkey::Pubkey,
  15. solana_signer::Signer,
  16. solana_test_validator::TestValidator,
  17. std::str::FromStr,
  18. };
  19. #[tokio::test(flavor = "multi_thread", worker_threads = 1)]
  20. async fn test_cli_create_extend_and_freeze_address_lookup_table() {
  21. let mint_keypair = Keypair::new();
  22. let faucet_addr = run_local_faucet_with_unique_port_for_tests(mint_keypair.insecure_clone());
  23. let test_validator = TestValidator::async_with_no_fees(
  24. &mint_keypair,
  25. Some(faucet_addr),
  26. SocketAddrSpace::Unspecified,
  27. )
  28. .await;
  29. let mut config = CliConfig::recent_for_tests();
  30. let keypair = Keypair::new();
  31. config.json_rpc_url = test_validator.rpc_url();
  32. config.signers = vec![&keypair];
  33. config.output_format = OutputFormat::JsonCompact;
  34. // Airdrop SOL for transaction fees
  35. config.command = CliCommand::Airdrop {
  36. pubkey: None,
  37. lamports: 10 * LAMPORTS_PER_SOL,
  38. };
  39. process_command(&config).await.unwrap();
  40. // Create lookup table
  41. config.command =
  42. CliCommand::AddressLookupTable(AddressLookupTableCliCommand::CreateLookupTable {
  43. authority_pubkey: keypair.pubkey(),
  44. payer_signer_index: 0,
  45. });
  46. let response: CliAddressLookupTableCreated =
  47. serde_json::from_str(&process_command(&config).await.unwrap()).unwrap();
  48. let lookup_table_pubkey = Pubkey::from_str(&response.lookup_table_address).unwrap();
  49. // Validate created lookup table
  50. {
  51. config.command =
  52. CliCommand::AddressLookupTable(AddressLookupTableCliCommand::ShowLookupTable {
  53. lookup_table_pubkey,
  54. });
  55. let response: CliAddressLookupTable =
  56. serde_json::from_str(&process_command(&config).await.unwrap()).unwrap();
  57. assert_eq!(
  58. response,
  59. CliAddressLookupTable {
  60. lookup_table_address: lookup_table_pubkey.to_string(),
  61. authority: Some(keypair.pubkey().to_string()),
  62. deactivation_slot: u64::MAX,
  63. last_extended_slot: 0,
  64. addresses: vec![],
  65. }
  66. );
  67. }
  68. // Extend lookup table
  69. let new_addresses: Vec<Pubkey> = (0..5).map(|_| Pubkey::new_unique()).collect();
  70. config.command =
  71. CliCommand::AddressLookupTable(AddressLookupTableCliCommand::ExtendLookupTable {
  72. lookup_table_pubkey,
  73. authority_signer_index: 0,
  74. payer_signer_index: 0,
  75. new_addresses: new_addresses.clone(),
  76. });
  77. process_command(&config).await.unwrap();
  78. // Validate extended lookup table
  79. {
  80. config.command =
  81. CliCommand::AddressLookupTable(AddressLookupTableCliCommand::ShowLookupTable {
  82. lookup_table_pubkey,
  83. });
  84. let CliAddressLookupTable {
  85. addresses,
  86. last_extended_slot,
  87. ..
  88. } = serde_json::from_str(&process_command(&config).await.unwrap()).unwrap();
  89. assert_eq!(
  90. addresses
  91. .into_iter()
  92. .map(|address| Pubkey::from_str(&address).unwrap())
  93. .collect::<Vec<Pubkey>>(),
  94. new_addresses
  95. );
  96. assert!(last_extended_slot > 0);
  97. }
  98. // Freeze lookup table w/o bypass
  99. config.command =
  100. CliCommand::AddressLookupTable(AddressLookupTableCliCommand::FreezeLookupTable {
  101. lookup_table_pubkey,
  102. authority_signer_index: 0,
  103. bypass_warning: false,
  104. });
  105. let process_err = process_command(&config).await.unwrap_err();
  106. assert_eq!(process_err.to_string(), FREEZE_LOOKUP_TABLE_WARNING);
  107. // Freeze lookup table w/ bypass
  108. config.command =
  109. CliCommand::AddressLookupTable(AddressLookupTableCliCommand::FreezeLookupTable {
  110. lookup_table_pubkey,
  111. authority_signer_index: 0,
  112. bypass_warning: true,
  113. });
  114. process_command(&config).await.unwrap();
  115. // Validate frozen lookup table
  116. {
  117. config.command =
  118. CliCommand::AddressLookupTable(AddressLookupTableCliCommand::ShowLookupTable {
  119. lookup_table_pubkey,
  120. });
  121. let CliAddressLookupTable { authority, .. } =
  122. serde_json::from_str(&process_command(&config).await.unwrap()).unwrap();
  123. assert!(authority.is_none());
  124. }
  125. }
  126. #[tokio::test(flavor = "multi_thread", worker_threads = 1)]
  127. async fn test_cli_create_and_deactivate_address_lookup_table() {
  128. let mint_keypair = Keypair::new();
  129. let faucet_addr = run_local_faucet_with_unique_port_for_tests(mint_keypair.insecure_clone());
  130. let test_validator = TestValidator::async_with_no_fees(
  131. &mint_keypair,
  132. Some(faucet_addr),
  133. SocketAddrSpace::Unspecified,
  134. )
  135. .await;
  136. let mut config = CliConfig::recent_for_tests();
  137. let keypair = Keypair::new();
  138. config.json_rpc_url = test_validator.rpc_url();
  139. config.signers = vec![&keypair];
  140. config.output_format = OutputFormat::JsonCompact;
  141. // Airdrop SOL for transaction fees
  142. config.command = CliCommand::Airdrop {
  143. pubkey: None,
  144. lamports: 10 * LAMPORTS_PER_SOL,
  145. };
  146. process_command(&config).await.unwrap();
  147. // Create lookup table
  148. config.command =
  149. CliCommand::AddressLookupTable(AddressLookupTableCliCommand::CreateLookupTable {
  150. authority_pubkey: keypair.pubkey(),
  151. payer_signer_index: 0,
  152. });
  153. let response: CliAddressLookupTableCreated =
  154. serde_json::from_str(&process_command(&config).await.unwrap()).unwrap();
  155. let lookup_table_pubkey = Pubkey::from_str(&response.lookup_table_address).unwrap();
  156. // Validate created lookup table
  157. {
  158. config.command =
  159. CliCommand::AddressLookupTable(AddressLookupTableCliCommand::ShowLookupTable {
  160. lookup_table_pubkey,
  161. });
  162. let response: CliAddressLookupTable =
  163. serde_json::from_str(&process_command(&config).await.unwrap()).unwrap();
  164. assert_eq!(
  165. response,
  166. CliAddressLookupTable {
  167. lookup_table_address: lookup_table_pubkey.to_string(),
  168. authority: Some(keypair.pubkey().to_string()),
  169. deactivation_slot: u64::MAX,
  170. last_extended_slot: 0,
  171. addresses: vec![],
  172. }
  173. );
  174. }
  175. // Deactivate lookup table w/o bypass
  176. config.command =
  177. CliCommand::AddressLookupTable(AddressLookupTableCliCommand::DeactivateLookupTable {
  178. lookup_table_pubkey,
  179. authority_signer_index: 0,
  180. bypass_warning: false,
  181. });
  182. let process_err = process_command(&config).await.unwrap_err();
  183. assert_eq!(process_err.to_string(), DEACTIVATE_LOOKUP_TABLE_WARNING);
  184. // Deactivate lookup table w/ bypass
  185. config.command =
  186. CliCommand::AddressLookupTable(AddressLookupTableCliCommand::DeactivateLookupTable {
  187. lookup_table_pubkey,
  188. authority_signer_index: 0,
  189. bypass_warning: true,
  190. });
  191. process_command(&config).await.unwrap();
  192. // Validate deactivated lookup table
  193. {
  194. config.command =
  195. CliCommand::AddressLookupTable(AddressLookupTableCliCommand::ShowLookupTable {
  196. lookup_table_pubkey,
  197. });
  198. let CliAddressLookupTable {
  199. deactivation_slot, ..
  200. } = serde_json::from_str(&process_command(&config).await.unwrap()).unwrap();
  201. assert_ne!(deactivation_slot, u64::MAX);
  202. }
  203. }