zero-copy.js 8.6 KB

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