account_access.rs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. // SPDX-License-Identifier: Apache-2.0
  2. use crate::borsh_encoding::BorshToken;
  3. use crate::{account_new, build_solidity, create_program_address, AccountState};
  4. use anchor_syn::idl::types::{IdlAccount, IdlAccountItem, IdlInstruction};
  5. #[test]
  6. fn access_payer() {
  7. let mut vm = build_solidity(
  8. r#"
  9. contract Test {
  10. @payer(payer)
  11. @seed("sunflower")
  12. @space(23)
  13. constructor(address my_payer) {
  14. assert(tx.accounts.payer.key == my_payer);
  15. assert(tx.accounts.payer.is_signer);
  16. assert(tx.accounts.payer.is_writable);
  17. }
  18. }
  19. "#,
  20. );
  21. let payer = account_new();
  22. let pda = create_program_address(&vm.stack[0].id, &[b"sunflower"]);
  23. vm.account_data.insert(
  24. payer,
  25. AccountState {
  26. data: Vec::new(),
  27. owner: None,
  28. lamports: 10,
  29. },
  30. );
  31. vm.account_data.insert(
  32. pda.0,
  33. AccountState {
  34. data: [0; 4096].to_vec(),
  35. owner: Some(vm.stack[0].id),
  36. lamports: 0,
  37. },
  38. );
  39. vm.function("new")
  40. .arguments(&[BorshToken::Address(payer)])
  41. .accounts(vec![
  42. ("dataAccount", pda.0),
  43. ("payer", payer),
  44. ("systemProgram", [0; 32]),
  45. ])
  46. .call();
  47. }
  48. #[test]
  49. fn fallback_magic() {
  50. let mut vm = build_solidity(
  51. r#"
  52. @program_id("5afzkvPkrshqu4onwBCsJccb1swrt4JdAjnpzK8N4BzZ")
  53. contract hatchling {
  54. string name;
  55. address private origin;
  56. constructor(string id, address parent) {
  57. require(id != "", "name must be provided");
  58. name = id;
  59. origin = parent;
  60. }
  61. function root() public returns (address) {
  62. return origin;
  63. }
  64. fallback() external {
  65. name = "wrong";
  66. }
  67. }
  68. "#,
  69. );
  70. let data_account = vm.initialize_data_account();
  71. let parent = account_new();
  72. vm.function("new")
  73. .arguments(&[
  74. BorshToken::String("my_id".to_string()),
  75. BorshToken::Address(parent),
  76. ])
  77. .accounts(vec![("dataAccount", data_account)])
  78. .call();
  79. if let Some(idl) = &mut vm.stack[0].idl {
  80. idl.instructions.push(IdlInstruction {
  81. name: "wrong".to_string(),
  82. docs: None,
  83. accounts: vec![IdlAccountItem::IdlAccount(IdlAccount {
  84. name: "dataAccount".to_string(),
  85. is_signer: false,
  86. is_optional: None,
  87. docs: None,
  88. pda: None,
  89. is_mut: true,
  90. relations: vec![],
  91. })],
  92. args: vec![],
  93. returns: None,
  94. });
  95. }
  96. // This should work
  97. vm.function("wrong")
  98. .accounts(vec![("dataAccount", data_account)])
  99. .call();
  100. vm.account_data.insert(parent, AccountState::default());
  101. // This should fail
  102. let res = vm
  103. .function("wrong")
  104. .accounts(vec![("dataAccount", parent)])
  105. .must_fail();
  106. assert_eq!(res.unwrap(), 2);
  107. }
  108. #[test]
  109. fn accounts_on_constructors() {
  110. let mut vm = build_solidity(
  111. r#"
  112. contract Test {
  113. @payer(my_payer)
  114. @account(acc1)
  115. @mutableAccount(acc2)
  116. @signer(acc3)
  117. @mutableSigner(acc4)
  118. constructor () {
  119. assert(tx.accounts.acc3.is_signer);
  120. assert(tx.accounts.acc4.is_signer);
  121. assert(tx.accounts.acc1.lamports == 5);
  122. tx.accounts.acc2.lamports -= 7;
  123. tx.accounts.acc4.lamports += 7;
  124. }
  125. }
  126. "#,
  127. );
  128. let data_account = vm.initialize_data_account();
  129. let acc1 = account_new();
  130. let acc2 = account_new();
  131. let acc3 = account_new();
  132. let acc4 = account_new();
  133. let my_payer = account_new();
  134. vm.account_data.insert(
  135. acc1,
  136. AccountState {
  137. data: vec![],
  138. owner: None,
  139. lamports: 5,
  140. },
  141. );
  142. vm.account_data.insert(
  143. acc2,
  144. AccountState {
  145. data: vec![],
  146. owner: None,
  147. lamports: 8,
  148. },
  149. );
  150. vm.account_data.insert(acc3, AccountState::default());
  151. vm.account_data.insert(
  152. acc4,
  153. AccountState {
  154. data: vec![],
  155. owner: None,
  156. lamports: 7,
  157. },
  158. );
  159. vm.account_data.insert(my_payer, AccountState::default());
  160. vm.function("new")
  161. .accounts(vec![
  162. ("dataAccount", data_account),
  163. ("acc1", acc1),
  164. ("acc2", acc2),
  165. ("acc3", acc3),
  166. ("acc4", acc4),
  167. ("my_payer", my_payer),
  168. ("systemProgram", [0; 32]),
  169. ])
  170. .call();
  171. assert_eq!(vm.account_data[&acc2].lamports, 1);
  172. assert_eq!(vm.account_data[&acc4].lamports, 14);
  173. }