binary-serializer.test.js 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. const { binary } = require('../dist/coretypes')
  2. const { encode, decode } = require('../dist')
  3. const { makeParser, BytesList, BinarySerializer } = binary
  4. const { coreTypes } = require('../dist/types')
  5. const { UInt8, UInt16, UInt32, UInt64, STObject } = coreTypes
  6. const bigInt = require('big-integer')
  7. const { Buffer } = require('buffer/')
  8. const { loadFixture } = require('./utils')
  9. const fixtures = loadFixture('data-driven-tests.json')
  10. const deliverMinTx = require('./fixtures/delivermin-tx.json')
  11. const deliverMinTxBinary = require('./fixtures/delivermin-tx-binary.json')
  12. const SignerListSet = {
  13. tx: require('./fixtures/signerlistset-tx.json'),
  14. binary: require('./fixtures/signerlistset-tx-binary.json'),
  15. meta: require('./fixtures/signerlistset-tx-meta-binary.json'),
  16. }
  17. const DepositPreauth = {
  18. tx: require('./fixtures/deposit-preauth-tx.json'),
  19. binary: require('./fixtures/deposit-preauth-tx-binary.json'),
  20. meta: require('./fixtures/deposit-preauth-tx-meta-binary.json'),
  21. }
  22. const Escrow = {
  23. create: {
  24. tx: require('./fixtures/escrow-create-tx.json'),
  25. binary: require('./fixtures/escrow-create-binary.json'),
  26. },
  27. finish: {
  28. tx: require('./fixtures/escrow-finish-tx.json'),
  29. binary: require('./fixtures/escrow-finish-binary.json'),
  30. meta: require('./fixtures/escrow-finish-meta-binary.json'),
  31. },
  32. cancel: {
  33. tx: require('./fixtures/escrow-cancel-tx.json'),
  34. binary: require('./fixtures/escrow-cancel-binary.json'),
  35. },
  36. }
  37. const PaymentChannel = {
  38. create: {
  39. tx: require('./fixtures/payment-channel-create-tx.json'),
  40. binary: require('./fixtures/payment-channel-create-binary.json'),
  41. },
  42. fund: {
  43. tx: require('./fixtures/payment-channel-fund-tx.json'),
  44. binary: require('./fixtures/payment-channel-fund-binary.json'),
  45. },
  46. claim: {
  47. tx: require('./fixtures/payment-channel-claim-tx.json'),
  48. binary: require('./fixtures/payment-channel-claim-binary.json'),
  49. },
  50. }
  51. const Ticket = {
  52. create: {
  53. tx: require('./fixtures/ticket-create-tx.json'),
  54. binary: require('./fixtures/ticket-create-binary.json'),
  55. },
  56. }
  57. let json_undefined = {
  58. TakerPays: '223174650',
  59. Account: 'rPk2dXr27rMw9G5Ej9ad2Tt7RJzGy8ycBp',
  60. TransactionType: 'OfferCreate',
  61. Memos: [
  62. {
  63. Memo: {
  64. MemoType: '584D4D2076616C7565',
  65. MemoData: '322E3230393635',
  66. MemoFormat: undefined,
  67. },
  68. },
  69. ],
  70. Fee: '15',
  71. OfferSequence: undefined,
  72. TakerGets: {
  73. currency: 'XMM',
  74. value: '100',
  75. issuer: 'rExAPEZvbkZqYPuNcZ7XEBLENEshsWDQc8',
  76. },
  77. Flags: 524288,
  78. Sequence: undefined,
  79. LastLedgerSequence: 6220135,
  80. }
  81. let json_omitted = {
  82. TakerPays: '223174650',
  83. Account: 'rPk2dXr27rMw9G5Ej9ad2Tt7RJzGy8ycBp',
  84. TransactionType: 'OfferCreate',
  85. Memos: [
  86. {
  87. Memo: {
  88. MemoType: '584D4D2076616C7565',
  89. MemoData: '322E3230393635',
  90. },
  91. },
  92. ],
  93. Fee: '15',
  94. TakerGets: {
  95. currency: 'XMM',
  96. value: '100',
  97. issuer: 'rExAPEZvbkZqYPuNcZ7XEBLENEshsWDQc8',
  98. },
  99. Flags: 524288,
  100. LastLedgerSequence: 6220135,
  101. }
  102. const NegativeUNL = require('./fixtures/negative-unl.json')
  103. function bytesListTest() {
  104. const list = new BytesList()
  105. .put(Buffer.from([0]))
  106. .put(Buffer.from([2, 3]))
  107. .put(Buffer.from([4, 5]))
  108. test('is an Array<Buffer>', function () {
  109. expect(Array.isArray(list.bytesArray)).toBe(true)
  110. expect(list.bytesArray[0] instanceof Buffer).toBe(true)
  111. })
  112. test('keeps track of the length itself', function () {
  113. expect(list.getLength()).toBe(5)
  114. })
  115. test('can join all arrays into one via toBytes', function () {
  116. const joined = list.toBytes()
  117. expect(joined).toHaveLength(5)
  118. expect(joined).toEqual(Buffer.from([0, 2, 3, 4, 5]))
  119. })
  120. }
  121. function assertRecycles(blob) {
  122. const parser = makeParser(blob)
  123. const so = parser.readType(STObject)
  124. const out = new BytesList()
  125. so.toBytesSink(out)
  126. const hex = out.toHex()
  127. expect(hex).toEqual(blob)
  128. expect(hex + ':').not.toEqual(blob)
  129. }
  130. function nestedObjectTests() {
  131. fixtures.whole_objects.forEach((f, i) => {
  132. test(`whole_objects[${i}]: can parse blob and dump out same blob`, () => {
  133. assertRecycles(f.blob_with_no_signing)
  134. })
  135. })
  136. }
  137. function check(type, n, expected) {
  138. test(`Uint${type.width * 8} serializes ${n} as ${expected}`, function () {
  139. const bl = new BytesList()
  140. const serializer = new BinarySerializer(bl)
  141. if (expected === 'throws') {
  142. expect(() => serializer.writeType(type, n)).toThrow()
  143. return
  144. }
  145. serializer.writeType(type, n)
  146. expect(bl.toBytes()).toEqual(Buffer.from(expected))
  147. })
  148. }
  149. check(UInt8, 5, [5])
  150. check(UInt16, 5, [0, 5])
  151. check(UInt32, 5, [0, 0, 0, 5])
  152. check(UInt32, 0xffffffff, [255, 255, 255, 255])
  153. check(UInt8, 0xfeffffff, 'throws')
  154. check(UInt16, 0xfeffffff, 'throws')
  155. check(UInt16, 0xfeffffff, 'throws')
  156. check(UInt64, 0xfeffffff, [0, 0, 0, 0, 254, 255, 255, 255])
  157. check(UInt64, -1, 'throws')
  158. check(UInt64, 0, [0, 0, 0, 0, 0, 0, 0, 0])
  159. check(UInt64, 1, [0, 0, 0, 0, 0, 0, 0, 1])
  160. check(UInt64, bigInt(1), [0, 0, 0, 0, 0, 0, 0, 1])
  161. function deliverMinTest() {
  162. test('can serialize DeliverMin', () => {
  163. expect(encode(deliverMinTx)).toEqual(deliverMinTxBinary)
  164. })
  165. }
  166. function SignerListSetTest() {
  167. test('can serialize SignerListSet', () => {
  168. expect(encode(SignerListSet.tx)).toEqual(SignerListSet.binary)
  169. })
  170. test('can serialize SignerListSet metadata', () => {
  171. expect(encode(SignerListSet.tx.meta)).toEqual(SignerListSet.meta)
  172. })
  173. }
  174. function DepositPreauthTest() {
  175. test('can serialize DepositPreauth', () => {
  176. expect(encode(DepositPreauth.tx)).toEqual(DepositPreauth.binary)
  177. })
  178. test('can serialize DepositPreauth metadata', () => {
  179. expect(encode(DepositPreauth.tx.meta)).toEqual(DepositPreauth.meta)
  180. })
  181. }
  182. function EscrowTest() {
  183. test('can serialize EscrowCreate', () => {
  184. expect(encode(Escrow.create.tx)).toEqual(Escrow.create.binary)
  185. })
  186. test('can serialize EscrowFinish', () => {
  187. expect(encode(Escrow.finish.tx)).toEqual(Escrow.finish.binary)
  188. expect(encode(Escrow.finish.tx.meta)).toEqual(Escrow.finish.meta)
  189. })
  190. test('can serialize EscrowCancel', () => {
  191. expect(encode(Escrow.cancel.tx)).toEqual(Escrow.cancel.binary)
  192. })
  193. }
  194. function PaymentChannelTest() {
  195. test('can serialize PaymentChannelCreate', () => {
  196. expect(encode(PaymentChannel.create.tx)).toEqual(
  197. PaymentChannel.create.binary,
  198. )
  199. })
  200. test('can serialize PaymentChannelFund', () => {
  201. expect(encode(PaymentChannel.fund.tx)).toEqual(PaymentChannel.fund.binary)
  202. })
  203. test('can serialize PaymentChannelClaim', () => {
  204. expect(encode(PaymentChannel.claim.tx)).toEqual(PaymentChannel.claim.binary)
  205. })
  206. }
  207. function NegativeUNLTest() {
  208. test('can serialize NegativeUNL', () => {
  209. expect(encode(NegativeUNL.tx)).toEqual(NegativeUNL.binary)
  210. })
  211. test('can deserialize NegativeUNL', () => {
  212. expect(decode(NegativeUNL.binary)).toEqual(NegativeUNL.tx)
  213. })
  214. }
  215. function omitUndefinedTest() {
  216. test('omits fields with undefined value', () => {
  217. let encodedOmitted = encode(json_omitted)
  218. let encodedUndefined = encode(json_undefined)
  219. expect(encodedOmitted).toEqual(encodedUndefined)
  220. expect(decode(encodedOmitted)).toEqual(decode(encodedUndefined))
  221. })
  222. }
  223. function ticketTest() {
  224. test('can serialize TicketCreate', () => {
  225. expect(encode(Ticket.create.tx)).toEqual(Ticket.create.binary)
  226. })
  227. }
  228. function nfTokenTest() {
  229. const fixtures = require('./fixtures/nf-token.json')
  230. for (const txName of Object.keys(fixtures)) {
  231. test(`can serialize transaction ${txName}`, () => {
  232. expect(encode(fixtures[txName].tx.json)).toEqual(
  233. fixtures[txName].tx.binary,
  234. )
  235. })
  236. test(`can deserialize transaction ${txName}`, () => {
  237. expect(decode(fixtures[txName].tx.binary)).toEqual(
  238. fixtures[txName].tx.json,
  239. )
  240. })
  241. test(`can serialize meta ${txName}`, () => {
  242. expect(encode(fixtures[txName].meta.json)).toEqual(
  243. fixtures[txName].meta.binary,
  244. )
  245. })
  246. test(`can deserialize meta ${txName}`, () => {
  247. expect(decode(fixtures[txName].meta.binary)).toEqual(
  248. fixtures[txName].meta.json,
  249. )
  250. })
  251. }
  252. }
  253. describe('Binary Serialization', function () {
  254. describe('nestedObjectTests', nestedObjectTests)
  255. describe('BytesList', bytesListTest)
  256. describe('DeliverMin', deliverMinTest)
  257. describe('DepositPreauth', DepositPreauthTest)
  258. describe('SignerListSet', SignerListSetTest)
  259. describe('Escrow', EscrowTest)
  260. describe('PaymentChannel', PaymentChannelTest)
  261. describe('NegativeUNLTest', NegativeUNLTest)
  262. describe('OmitUndefined', omitUndefinedTest)
  263. describe('TicketTest', ticketTest)
  264. describe('NFToken', nfTokenTest)
  265. })