zero-copy.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  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 programCpi = anchor.workspace.ZeroCpi
  10. const foo = anchor.web3.Keypair.generate()
  11. it('Is creates a zero copy account', async () => {
  12. await program.rpc.createFoo({
  13. accounts: {
  14. foo: foo.publicKey,
  15. authority: program.provider.wallet.publicKey,
  16. rent: anchor.web3.SYSVAR_RENT_PUBKEY,
  17. },
  18. instructions: [await program.account.foo.createInstruction(foo)],
  19. signers: [foo],
  20. })
  21. const account = await program.account.foo.fetch(foo.publicKey)
  22. assert.ok(
  23. JSON.stringify(account.authority.toBuffer()) ===
  24. JSON.stringify(program.provider.wallet.publicKey.toBuffer())
  25. )
  26. assert.ok(account.data.toNumber() === 0)
  27. assert.ok(account.secondData.toNumber() === 0)
  28. assert.ok(
  29. JSON.stringify(account.secondAuthority) ===
  30. JSON.stringify([...program.provider.wallet.publicKey.toBuffer()])
  31. )
  32. })
  33. it('Updates a zero copy account field', async () => {
  34. await program.rpc.updateFoo(new BN(1234), {
  35. accounts: {
  36. foo: foo.publicKey,
  37. authority: program.provider.wallet.publicKey,
  38. },
  39. })
  40. const account = await program.account.foo.fetch(foo.publicKey)
  41. assert.ok(
  42. JSON.stringify(account.authority.toBuffer()) ===
  43. JSON.stringify(program.provider.wallet.publicKey.toBuffer())
  44. )
  45. assert.ok(account.data.toNumber() === 1234)
  46. assert.ok(account.secondData.toNumber() === 0)
  47. assert.ok(
  48. JSON.stringify(account.secondAuthority) ===
  49. JSON.stringify([...program.provider.wallet.publicKey.toBuffer()])
  50. )
  51. })
  52. it('Updates a a second zero copy account field', async () => {
  53. await program.rpc.updateFooSecond(new BN(55), {
  54. accounts: {
  55. foo: foo.publicKey,
  56. secondAuthority: program.provider.wallet.publicKey,
  57. },
  58. })
  59. const account = await program.account.foo.fetch(foo.publicKey)
  60. assert.ok(
  61. JSON.stringify(account.authority.toBuffer()) ===
  62. JSON.stringify(program.provider.wallet.publicKey.toBuffer())
  63. )
  64. assert.ok(account.data.toNumber() === 1234)
  65. assert.ok(account.secondData.toNumber() === 55)
  66. assert.ok(
  67. JSON.stringify(account.secondAuthority) ===
  68. JSON.stringify([...program.provider.wallet.publicKey.toBuffer()])
  69. )
  70. })
  71. it('Creates an associated zero copy account', async () => {
  72. await program.rpc.createBar({
  73. accounts: {
  74. bar: (
  75. await PublicKey.findProgramAddress(
  76. [program.provider.wallet.publicKey.toBuffer(), foo.publicKey.toBuffer()],
  77. program.programId
  78. )
  79. )[0],
  80. authority: program.provider.wallet.publicKey,
  81. foo: foo.publicKey,
  82. systemProgram: anchor.web3.SystemProgram.programId,
  83. },
  84. })
  85. const bar = (
  86. await PublicKey.findProgramAddress(
  87. [program.provider.wallet.publicKey.toBuffer(), foo.publicKey.toBuffer()],
  88. program.programId
  89. )
  90. )[0]
  91. const barAccount = await program.account.bar.fetch(bar)
  92. assert.ok(barAccount.authority.equals(program.provider.wallet.publicKey))
  93. assert.ok(barAccount.data.toNumber() === 0)
  94. })
  95. it('Updates an associated zero copy account', async () => {
  96. const bar = (
  97. await PublicKey.findProgramAddress(
  98. [program.provider.wallet.publicKey.toBuffer(), foo.publicKey.toBuffer()],
  99. program.programId
  100. )
  101. )[0]
  102. await program.rpc.updateBar(new BN(99), {
  103. accounts: {
  104. bar,
  105. authority: program.provider.wallet.publicKey,
  106. foo: foo.publicKey,
  107. },
  108. })
  109. const barAccount = await program.account.bar.fetch(bar)
  110. assert.ok(barAccount.authority.equals(program.provider.wallet.publicKey))
  111. assert.ok(barAccount.data.toNumber() === 99)
  112. // Check zero_copy CPI
  113. await programCpi.rpc.checkCpi(new BN(1337), {
  114. accounts: {
  115. bar,
  116. authority: program.provider.wallet.publicKey,
  117. foo: foo.publicKey,
  118. zeroCopyProgram: program.programId,
  119. },
  120. })
  121. const barAccountAfterCpi = await program.account.bar.fetch(bar)
  122. assert.ok(barAccountAfterCpi.authority.equals(program.provider.wallet.publicKey))
  123. assert.ok(barAccountAfterCpi.data.toNumber() === 1337)
  124. })
  125. const eventQ = anchor.web3.Keypair.generate()
  126. const size = 1000000 + 8 // Account size in bytes.
  127. it('Creates a large event queue', async () => {
  128. await program.rpc.createLargeAccount({
  129. accounts: {
  130. eventQ: eventQ.publicKey,
  131. rent: anchor.web3.SYSVAR_RENT_PUBKEY,
  132. },
  133. instructions: [await program.account.eventQ.createInstruction(eventQ, size)],
  134. signers: [eventQ],
  135. })
  136. const account = await program.account.eventQ.fetch(eventQ.publicKey)
  137. assert.ok(account.events.length === 25000)
  138. account.events.forEach((event) => {
  139. assert.ok(event.from.equals(PublicKey.default))
  140. assert.ok(event.data.toNumber() === 0)
  141. })
  142. })
  143. it('Updates a large event queue', async () => {
  144. // Set index 0.
  145. await program.rpc.updateLargeAccount(0, new BN(48), {
  146. accounts: {
  147. eventQ: eventQ.publicKey,
  148. from: program.provider.wallet.publicKey,
  149. },
  150. })
  151. // Verify update.
  152. let account = await program.account.eventQ.fetch(eventQ.publicKey)
  153. assert.ok(account.events.length === 25000)
  154. account.events.forEach((event, idx) => {
  155. if (idx === 0) {
  156. assert.ok(event.from.equals(program.provider.wallet.publicKey))
  157. assert.ok(event.data.toNumber() === 48)
  158. } else {
  159. assert.ok(event.from.equals(PublicKey.default))
  160. assert.ok(event.data.toNumber() === 0)
  161. }
  162. })
  163. // Set index 11111.
  164. await program.rpc.updateLargeAccount(11111, new BN(1234), {
  165. accounts: {
  166. eventQ: eventQ.publicKey,
  167. from: program.provider.wallet.publicKey,
  168. },
  169. })
  170. // Verify update.
  171. account = await program.account.eventQ.fetch(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 if (idx === 11111) {
  178. assert.ok(event.from.equals(program.provider.wallet.publicKey))
  179. assert.ok(event.data.toNumber() === 1234)
  180. } else {
  181. assert.ok(event.from.equals(PublicKey.default))
  182. assert.ok(event.data.toNumber() === 0)
  183. }
  184. })
  185. // Set last index.
  186. await program.rpc.updateLargeAccount(24999, new BN(99), {
  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 if (idx === 24999) {
  203. assert.ok(event.from.equals(program.provider.wallet.publicKey))
  204. assert.ok(event.data.toNumber() === 99)
  205. } else {
  206. assert.ok(event.from.equals(PublicKey.default))
  207. assert.ok(event.data.toNumber() === 0)
  208. }
  209. })
  210. })
  211. it('Errors when setting an out of bounds index', async () => {
  212. // Fail to set non existing index.
  213. await assert.rejects(
  214. async () => {
  215. await program.rpc.updateLargeAccount(25000, new BN(1), {
  216. accounts: {
  217. eventQ: eventQ.publicKey,
  218. from: program.provider.wallet.publicKey,
  219. },
  220. })
  221. },
  222. (err) => {
  223. console.log('err', err)
  224. return true
  225. }
  226. )
  227. })
  228. })