zero-copy.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. const anchor = require("@project-serum/anchor");
  2. const assert = require("assert");
  3. describe("zero-copy", () => {
  4. // Configure the client to use the local cluster.
  5. anchor.setProvider(anchor.Provider.env());
  6. const program = anchor.workspace.ZeroCopy;
  7. const foo = new anchor.web3.Account();
  8. it("Creates zero copy state", async () => {
  9. await program.state.rpc.new({
  10. accounts: {
  11. authority: program.provider.wallet.publicKey,
  12. },
  13. });
  14. const state = await program.state();
  15. assert.ok(state.authority.equals(program.provider.wallet.publicKey));
  16. assert.ok(state.events.length === 250);
  17. state.events.forEach((event, idx) => {
  18. assert.ok(event.from.equals(new anchor.web3.PublicKey()));
  19. assert.ok(event.data.toNumber() === 0);
  20. });
  21. });
  22. it("Updates zero copy state", async () => {
  23. let event = {
  24. from: new anchor.web3.PublicKey(),
  25. data: new anchor.BN(1234),
  26. };
  27. await program.state.rpc.setEvent(5, event, {
  28. accounts: {
  29. authority: program.provider.wallet.publicKey,
  30. },
  31. });
  32. const state = await program.state();
  33. assert.ok(state.authority.equals(program.provider.wallet.publicKey));
  34. assert.ok(state.events.length === 250);
  35. state.events.forEach((event, idx) => {
  36. if (idx === 5) {
  37. assert.ok(event.from.equals(event.from));
  38. assert.ok(event.data.eq(event.data));
  39. } else {
  40. assert.ok(event.from.equals(new anchor.web3.PublicKey()));
  41. assert.ok(event.data.toNumber() === 0);
  42. }
  43. });
  44. });
  45. it("Is creates a zero copy account", async () => {
  46. await program.rpc.createFoo({
  47. accounts: {
  48. foo: foo.publicKey,
  49. authority: program.provider.wallet.publicKey,
  50. rent: anchor.web3.SYSVAR_RENT_PUBKEY,
  51. },
  52. instructions: [await program.account.foo.createInstruction(foo)],
  53. signers: [foo],
  54. });
  55. const account = await program.account.foo(foo.publicKey);
  56. assert.ok(
  57. JSON.stringify(account.authority.toBuffer()) ===
  58. JSON.stringify(program.provider.wallet.publicKey.toBuffer())
  59. );
  60. assert.ok(account.data.toNumber() === 0);
  61. assert.ok(account.secondData.toNumber() === 0);
  62. assert.ok(
  63. JSON.stringify(account.secondAuthority) ===
  64. JSON.stringify([...program.provider.wallet.publicKey.toBuffer()])
  65. );
  66. });
  67. it("Updates a zero copy account field", async () => {
  68. await program.rpc.updateFoo(new anchor.BN(1234), {
  69. accounts: {
  70. foo: foo.publicKey,
  71. authority: program.provider.wallet.publicKey,
  72. },
  73. });
  74. const account = await program.account.foo(foo.publicKey);
  75. assert.ok(
  76. JSON.stringify(account.authority.toBuffer()) ===
  77. JSON.stringify(program.provider.wallet.publicKey.toBuffer())
  78. );
  79. assert.ok(account.data.toNumber() === 1234);
  80. assert.ok(account.secondData.toNumber() === 0);
  81. assert.ok(
  82. JSON.stringify(account.secondAuthority) ===
  83. JSON.stringify([...program.provider.wallet.publicKey.toBuffer()])
  84. );
  85. });
  86. it("Updates a a second zero copy account field", async () => {
  87. await program.rpc.updateFooSecond(new anchor.BN(55), {
  88. accounts: {
  89. foo: foo.publicKey,
  90. secondAuthority: program.provider.wallet.publicKey,
  91. },
  92. });
  93. const account = await program.account.foo(foo.publicKey);
  94. assert.ok(
  95. JSON.stringify(account.authority.toBuffer()) ===
  96. JSON.stringify(program.provider.wallet.publicKey.toBuffer())
  97. );
  98. assert.ok(account.data.toNumber() === 1234);
  99. assert.ok(account.secondData.toNumber() === 55);
  100. assert.ok(
  101. JSON.stringify(account.secondAuthority) ===
  102. JSON.stringify([...program.provider.wallet.publicKey.toBuffer()])
  103. );
  104. });
  105. it("Creates an associated zero copy account", async () => {
  106. await program.rpc.createBar({
  107. accounts: {
  108. bar: await program.account.bar.associatedAddress(
  109. program.provider.wallet.publicKey,
  110. foo.publicKey
  111. ),
  112. authority: program.provider.wallet.publicKey,
  113. foo: foo.publicKey,
  114. rent: anchor.web3.SYSVAR_RENT_PUBKEY,
  115. systemProgram: anchor.web3.SystemProgram.programId,
  116. },
  117. });
  118. const bar = await program.account.bar.associated(
  119. program.provider.wallet.publicKey,
  120. foo.publicKey
  121. );
  122. assert.ok(bar.authority.equals(program.provider.wallet.publicKey));
  123. assert.ok(bar.data.toNumber() === 0);
  124. });
  125. it("Updates an associated zero copy account", async () => {
  126. await program.rpc.updateBar(new anchor.BN(99), {
  127. accounts: {
  128. bar: await program.account.bar.associatedAddress(
  129. program.provider.wallet.publicKey,
  130. foo.publicKey
  131. ),
  132. authority: program.provider.wallet.publicKey,
  133. },
  134. });
  135. const bar = await program.account.bar.associated(
  136. program.provider.wallet.publicKey,
  137. foo.publicKey
  138. );
  139. assert.ok(bar.authority.equals(program.provider.wallet.publicKey));
  140. assert.ok(bar.data.toNumber() === 99);
  141. });
  142. const eventQ = new anchor.web3.Account();
  143. const size = 1000000 + 8; // Account size in bytes.
  144. it("Creates a large event queue", async () => {
  145. await program.rpc.createLargeAccount({
  146. accounts: {
  147. eventQ: eventQ.publicKey,
  148. rent: anchor.web3.SYSVAR_RENT_PUBKEY,
  149. },
  150. instructions: [
  151. await program.account.eventQ.createInstruction(eventQ, size),
  152. ],
  153. signers: [eventQ],
  154. });
  155. const account = await program.account.eventQ(eventQ.publicKey);
  156. assert.ok(account.events.length === 25000);
  157. account.events.forEach((event) => {
  158. assert.ok(event.from.equals(new anchor.web3.PublicKey()));
  159. assert.ok(event.data.toNumber() === 0);
  160. });
  161. });
  162. it("Updates a large event queue", async () => {
  163. // Set index 0.
  164. await program.rpc.updateLargeAccount(0, new anchor.BN(48), {
  165. accounts: {
  166. eventQ: eventQ.publicKey,
  167. from: program.provider.wallet.publicKey,
  168. },
  169. });
  170. // Verify update.
  171. let account = await program.account.eventQ(eventQ.publicKey);
  172. assert.ok(account.events.length === 25000);
  173. account.events.forEach((event, idx) => {
  174. if (idx === 0) {
  175. assert.ok(event.from.equals(program.provider.wallet.publicKey));
  176. assert.ok(event.data.toNumber() === 48);
  177. } else {
  178. assert.ok(event.from.equals(new anchor.web3.PublicKey()));
  179. assert.ok(event.data.toNumber() === 0);
  180. }
  181. });
  182. // Set index 11111.
  183. await program.rpc.updateLargeAccount(11111, new anchor.BN(1234), {
  184. accounts: {
  185. eventQ: eventQ.publicKey,
  186. from: program.provider.wallet.publicKey,
  187. },
  188. });
  189. // Verify update.
  190. account = await program.account.eventQ(eventQ.publicKey);
  191. assert.ok(account.events.length === 25000);
  192. account.events.forEach((event, idx) => {
  193. if (idx === 0) {
  194. assert.ok(event.from.equals(program.provider.wallet.publicKey));
  195. assert.ok(event.data.toNumber() === 48);
  196. } else if (idx === 11111) {
  197. assert.ok(event.from.equals(program.provider.wallet.publicKey));
  198. assert.ok(event.data.toNumber() === 1234);
  199. } else {
  200. assert.ok(event.from.equals(new anchor.web3.PublicKey()));
  201. assert.ok(event.data.toNumber() === 0);
  202. }
  203. });
  204. // Set last index.
  205. await program.rpc.updateLargeAccount(24999, new anchor.BN(99), {
  206. accounts: {
  207. eventQ: eventQ.publicKey,
  208. from: program.provider.wallet.publicKey,
  209. },
  210. });
  211. // Verify update.
  212. account = await program.account.eventQ(eventQ.publicKey);
  213. assert.ok(account.events.length === 25000);
  214. account.events.forEach((event, idx) => {
  215. if (idx === 0) {
  216. assert.ok(event.from.equals(program.provider.wallet.publicKey));
  217. assert.ok(event.data.toNumber() === 48);
  218. } else if (idx === 11111) {
  219. assert.ok(event.from.equals(program.provider.wallet.publicKey));
  220. assert.ok(event.data.toNumber() === 1234);
  221. } else if (idx === 24999) {
  222. assert.ok(event.from.equals(program.provider.wallet.publicKey));
  223. assert.ok(event.data.toNumber() === 99);
  224. } else {
  225. assert.ok(event.from.equals(new anchor.web3.PublicKey()));
  226. assert.ok(event.data.toNumber() === 0);
  227. }
  228. });
  229. });
  230. it("Errors when setting an out of bounds index", async () => {
  231. // Fail to set non existing index.
  232. await assert.rejects(
  233. async () => {
  234. await program.rpc.updateLargeAccount(25000, new anchor.BN(1), {
  235. accounts: {
  236. eventQ: eventQ.publicKey,
  237. from: program.provider.wallet.publicKey,
  238. },
  239. });
  240. },
  241. (err) => {
  242. console.log("err", err);
  243. return true;
  244. }
  245. );
  246. });
  247. });