zero-copy.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  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: (
  111. await PublicKey.findProgramAddress(
  112. [
  113. program.provider.wallet.publicKey.toBuffer(),
  114. foo.publicKey.toBuffer(),
  115. ],
  116. program.programId
  117. )
  118. )[0],
  119. authority: program.provider.wallet.publicKey,
  120. foo: foo.publicKey,
  121. systemProgram: anchor.web3.SystemProgram.programId,
  122. },
  123. });
  124. const bar = (
  125. await PublicKey.findProgramAddress(
  126. [
  127. program.provider.wallet.publicKey.toBuffer(),
  128. foo.publicKey.toBuffer(),
  129. ],
  130. program.programId
  131. )
  132. )[0];
  133. const barAccount = await program.account.bar.fetch(bar);
  134. assert.ok(barAccount.authority.equals(program.provider.wallet.publicKey));
  135. assert.ok(barAccount.data.toNumber() === 0);
  136. });
  137. it("Updates an associated zero copy account", async () => {
  138. const bar = (
  139. await PublicKey.findProgramAddress(
  140. [
  141. program.provider.wallet.publicKey.toBuffer(),
  142. foo.publicKey.toBuffer(),
  143. ],
  144. program.programId
  145. )
  146. )[0];
  147. await program.rpc.updateBar(new BN(99), {
  148. accounts: {
  149. bar,
  150. authority: program.provider.wallet.publicKey,
  151. foo: foo.publicKey,
  152. },
  153. });
  154. const barAccount = await program.account.bar.fetch(bar);
  155. assert.ok(barAccount.authority.equals(program.provider.wallet.publicKey));
  156. assert.ok(barAccount.data.toNumber() === 99);
  157. });
  158. const eventQ = anchor.web3.Keypair.generate();
  159. const size = 1000000 + 8; // Account size in bytes.
  160. it("Creates a large event queue", async () => {
  161. await program.rpc.createLargeAccount({
  162. accounts: {
  163. eventQ: eventQ.publicKey,
  164. rent: anchor.web3.SYSVAR_RENT_PUBKEY,
  165. },
  166. instructions: [
  167. await program.account.eventQ.createInstruction(eventQ, size),
  168. ],
  169. signers: [eventQ],
  170. });
  171. const account = await program.account.eventQ.fetch(eventQ.publicKey);
  172. assert.ok(account.events.length === 25000);
  173. account.events.forEach((event) => {
  174. assert.ok(event.from.equals(PublicKey.default));
  175. assert.ok(event.data.toNumber() === 0);
  176. });
  177. });
  178. it("Updates a large event queue", async () => {
  179. // Set index 0.
  180. await program.rpc.updateLargeAccount(0, new BN(48), {
  181. accounts: {
  182. eventQ: eventQ.publicKey,
  183. from: program.provider.wallet.publicKey,
  184. },
  185. });
  186. // Verify update.
  187. let account = await program.account.eventQ.fetch(eventQ.publicKey);
  188. assert.ok(account.events.length === 25000);
  189. account.events.forEach((event, idx) => {
  190. if (idx === 0) {
  191. assert.ok(event.from.equals(program.provider.wallet.publicKey));
  192. assert.ok(event.data.toNumber() === 48);
  193. } else {
  194. assert.ok(event.from.equals(PublicKey.default));
  195. assert.ok(event.data.toNumber() === 0);
  196. }
  197. });
  198. // Set index 11111.
  199. await program.rpc.updateLargeAccount(11111, new BN(1234), {
  200. accounts: {
  201. eventQ: eventQ.publicKey,
  202. from: program.provider.wallet.publicKey,
  203. },
  204. });
  205. // Verify update.
  206. account = await program.account.eventQ.fetch(eventQ.publicKey);
  207. assert.ok(account.events.length === 25000);
  208. account.events.forEach((event, idx) => {
  209. if (idx === 0) {
  210. assert.ok(event.from.equals(program.provider.wallet.publicKey));
  211. assert.ok(event.data.toNumber() === 48);
  212. } else if (idx === 11111) {
  213. assert.ok(event.from.equals(program.provider.wallet.publicKey));
  214. assert.ok(event.data.toNumber() === 1234);
  215. } else {
  216. assert.ok(event.from.equals(PublicKey.default));
  217. assert.ok(event.data.toNumber() === 0);
  218. }
  219. });
  220. // Set last index.
  221. await program.rpc.updateLargeAccount(24999, new BN(99), {
  222. accounts: {
  223. eventQ: eventQ.publicKey,
  224. from: program.provider.wallet.publicKey,
  225. },
  226. });
  227. // Verify update.
  228. account = await program.account.eventQ.fetch(eventQ.publicKey);
  229. assert.ok(account.events.length === 25000);
  230. account.events.forEach((event, idx) => {
  231. if (idx === 0) {
  232. assert.ok(event.from.equals(program.provider.wallet.publicKey));
  233. assert.ok(event.data.toNumber() === 48);
  234. } else if (idx === 11111) {
  235. assert.ok(event.from.equals(program.provider.wallet.publicKey));
  236. assert.ok(event.data.toNumber() === 1234);
  237. } else if (idx === 24999) {
  238. assert.ok(event.from.equals(program.provider.wallet.publicKey));
  239. assert.ok(event.data.toNumber() === 99);
  240. } else {
  241. assert.ok(event.from.equals(PublicKey.default));
  242. assert.ok(event.data.toNumber() === 0);
  243. }
  244. });
  245. });
  246. it("Errors when setting an out of bounds index", async () => {
  247. // Fail to set non existing index.
  248. await assert.rejects(
  249. async () => {
  250. await program.rpc.updateLargeAccount(25000, new BN(1), {
  251. accounts: {
  252. eventQ: eventQ.publicKey,
  253. from: program.provider.wallet.publicKey,
  254. },
  255. });
  256. },
  257. (err) => {
  258. console.log("err", err);
  259. return true;
  260. }
  261. );
  262. });
  263. });