writer_test.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. package lnwire
  2. import (
  3. "bytes"
  4. "encoding/base32"
  5. "image/color"
  6. "math"
  7. "net"
  8. "testing"
  9. "github.com/btcsuite/btcd/btcutil"
  10. "github.com/btcsuite/btcd/chaincfg/chainhash"
  11. "github.com/btcsuite/btcd/wire"
  12. "github.com/lightningnetwork/lnd/tor"
  13. "github.com/stretchr/testify/require"
  14. )
  15. func TestWriteBytes(t *testing.T) {
  16. buf := new(bytes.Buffer)
  17. data := []byte{1, 2, 3}
  18. err := WriteBytes(buf, data)
  19. require.NoError(t, err)
  20. require.Equal(t, data, buf.Bytes())
  21. }
  22. func TestWriteUint8(t *testing.T) {
  23. buf := new(bytes.Buffer)
  24. data := uint8(1)
  25. expectedBytes := []byte{1}
  26. err := WriteUint8(buf, data)
  27. require.NoError(t, err)
  28. require.Equal(t, expectedBytes, buf.Bytes())
  29. }
  30. func TestWriteUint16(t *testing.T) {
  31. buf := new(bytes.Buffer)
  32. data := uint16(1)
  33. expectedBytes := []byte{0, 1}
  34. err := WriteUint16(buf, data)
  35. require.NoError(t, err)
  36. require.Equal(t, expectedBytes, buf.Bytes())
  37. }
  38. func TestWriteUint32(t *testing.T) {
  39. buf := new(bytes.Buffer)
  40. data := uint32(1)
  41. expectedBytes := []byte{0, 0, 0, 1}
  42. err := WriteUint32(buf, data)
  43. require.NoError(t, err)
  44. require.Equal(t, expectedBytes, buf.Bytes())
  45. }
  46. func TestWriteUint64(t *testing.T) {
  47. buf := new(bytes.Buffer)
  48. data := uint64(1)
  49. expectedBytes := []byte{0, 0, 0, 0, 0, 0, 0, 1}
  50. err := WriteUint64(buf, data)
  51. require.NoError(t, err)
  52. require.Equal(t, expectedBytes, buf.Bytes())
  53. }
  54. func TestWriteSatoshi(t *testing.T) {
  55. buf := new(bytes.Buffer)
  56. data := btcutil.Amount(1)
  57. expectedBytes := []byte{0, 0, 0, 0, 0, 0, 0, 1}
  58. err := WriteSatoshi(buf, data)
  59. require.NoError(t, err)
  60. require.Equal(t, expectedBytes, buf.Bytes())
  61. }
  62. func TestWriteMilliSatoshi(t *testing.T) {
  63. buf := new(bytes.Buffer)
  64. data := MilliSatoshi(1)
  65. expectedBytes := []byte{0, 0, 0, 0, 0, 0, 0, 1}
  66. err := WriteMilliSatoshi(buf, data)
  67. require.NoError(t, err)
  68. require.Equal(t, expectedBytes, buf.Bytes())
  69. }
  70. func TestWritePublicKey(t *testing.T) {
  71. buf := new(bytes.Buffer)
  72. // Check that when nil pubkey is used, an error will return.
  73. err := WritePublicKey(buf, nil)
  74. require.Equal(t, ErrNilPublicKey, err)
  75. pub, err := randPubKey()
  76. require.NoError(t, err)
  77. expectedBytes := pub.SerializeCompressed()
  78. err = WritePublicKey(buf, pub)
  79. require.NoError(t, err)
  80. require.Equal(t, expectedBytes, buf.Bytes())
  81. }
  82. func TestWriteChannelID(t *testing.T) {
  83. buf := new(bytes.Buffer)
  84. data := ChannelID{1}
  85. expectedBytes := [32]byte{1}
  86. err := WriteChannelID(buf, data)
  87. require.NoError(t, err)
  88. require.Equal(t, expectedBytes[:], buf.Bytes())
  89. }
  90. func TestWriteNodeAlias(t *testing.T) {
  91. buf := new(bytes.Buffer)
  92. data := NodeAlias{1}
  93. expectedBytes := [32]byte{1}
  94. err := WriteNodeAlias(buf, data)
  95. require.NoError(t, err)
  96. require.Equal(t, expectedBytes[:], buf.Bytes())
  97. }
  98. func TestWriteShortChannelID(t *testing.T) {
  99. buf := new(bytes.Buffer)
  100. data := ShortChannelID{BlockHeight: 1, TxIndex: 2, TxPosition: 3}
  101. expectedBytes := []byte{
  102. 0, 0, 1, // First three bytes encodes BlockHeight.
  103. 0, 0, 2, // Second three bytes encodes TxIndex.
  104. 0, 3, // Final two bytes encodes TxPosition.
  105. }
  106. err := WriteShortChannelID(buf, data)
  107. require.NoError(t, err)
  108. require.Equal(t, expectedBytes, buf.Bytes())
  109. }
  110. func TestWriteSig(t *testing.T) {
  111. buf := new(bytes.Buffer)
  112. data := Sig{
  113. bytes: [64]byte{1, 2, 3},
  114. }
  115. expectedBytes := [64]byte{1, 2, 3}
  116. err := WriteSig(buf, data)
  117. require.NoError(t, err)
  118. require.Equal(t, expectedBytes[:], buf.Bytes())
  119. }
  120. func TestWriteSigs(t *testing.T) {
  121. buf := new(bytes.Buffer)
  122. sig1 := Sig{bytes: [64]byte{1}}
  123. sig2 := Sig{bytes: [64]byte{2}}
  124. sig3 := Sig{bytes: [64]byte{3}}
  125. data := []Sig{sig1, sig2, sig3}
  126. // First two bytes encode the length of the slice.
  127. expectedBytes := []byte{0, 3}
  128. expectedBytes = append(expectedBytes, sig1.bytes[:]...)
  129. expectedBytes = append(expectedBytes, sig2.bytes[:]...)
  130. expectedBytes = append(expectedBytes, sig3.bytes[:]...)
  131. err := WriteSigs(buf, data)
  132. require.NoError(t, err)
  133. require.Equal(t, expectedBytes, buf.Bytes())
  134. }
  135. func TestWriteFailCode(t *testing.T) {
  136. buf := new(bytes.Buffer)
  137. data := FailCode(1)
  138. expectedBytes := []byte{0, 1}
  139. err := WriteFailCode(buf, data)
  140. require.NoError(t, err)
  141. require.Equal(t, expectedBytes, buf.Bytes())
  142. }
  143. // TODO(yy): expand the test to cover more encoding scenarios.
  144. func TestWriteRawFeatureVector(t *testing.T) {
  145. buf := new(bytes.Buffer)
  146. // Check that when nil feature is used, an error will return.
  147. err := WriteRawFeatureVector(buf, nil)
  148. require.Equal(t, ErrNilFeatureVector, err)
  149. // Create a raw feature vector.
  150. feature := &RawFeatureVector{
  151. features: map[FeatureBit]struct{}{
  152. InitialRoutingSync: {}, // FeatureBit 3.
  153. },
  154. }
  155. expectedBytes := []byte{
  156. 0, 1, // First two bytes encode the length.
  157. 8, // Last byte encodes the feature bit (1 << 3).
  158. }
  159. err = WriteRawFeatureVector(buf, feature)
  160. require.NoError(t, err)
  161. require.Equal(t, expectedBytes, buf.Bytes())
  162. }
  163. func TestWriteColorRGBA(t *testing.T) {
  164. buf := new(bytes.Buffer)
  165. data := color.RGBA{R: 1, G: 2, B: 3}
  166. expectedBytes := []byte{1, 2, 3}
  167. err := WriteColorRGBA(buf, data)
  168. require.NoError(t, err)
  169. require.Equal(t, expectedBytes, buf.Bytes())
  170. }
  171. func TestWriteShortChanIDEncoding(t *testing.T) {
  172. buf := new(bytes.Buffer)
  173. data := QueryEncoding(1)
  174. expectedBytes := []byte{1}
  175. err := WriteQueryEncoding(buf, data)
  176. require.NoError(t, err)
  177. require.Equal(t, expectedBytes, buf.Bytes())
  178. }
  179. func TestWriteFundingFlag(t *testing.T) {
  180. buf := new(bytes.Buffer)
  181. data := FundingFlag(1)
  182. expectedBytes := []byte{1}
  183. err := WriteFundingFlag(buf, data)
  184. require.NoError(t, err)
  185. require.Equal(t, expectedBytes, buf.Bytes())
  186. }
  187. func TestWriteChanUpdateMsgFlags(t *testing.T) {
  188. buf := new(bytes.Buffer)
  189. data := ChanUpdateMsgFlags(1)
  190. expectedBytes := []byte{1}
  191. err := WriteChanUpdateMsgFlags(buf, data)
  192. require.NoError(t, err)
  193. require.Equal(t, expectedBytes, buf.Bytes())
  194. }
  195. func TestWriteChanUpdateChanFlags(t *testing.T) {
  196. buf := new(bytes.Buffer)
  197. data := ChanUpdateChanFlags(1)
  198. expectedBytes := []byte{1}
  199. err := WriteChanUpdateChanFlags(buf, data)
  200. require.NoError(t, err)
  201. require.Equal(t, expectedBytes, buf.Bytes())
  202. }
  203. func TestWriteDeliveryAddress(t *testing.T) {
  204. buf := new(bytes.Buffer)
  205. data := DeliveryAddress{1, 1, 1}
  206. expectedBytes := []byte{
  207. 0, 3, // First two bytes encode the length.
  208. 1, 1, 1, // The actual data.
  209. }
  210. err := WriteDeliveryAddress(buf, data)
  211. require.NoError(t, err)
  212. require.Equal(t, expectedBytes, buf.Bytes())
  213. }
  214. func TestWritePingPayload(t *testing.T) {
  215. buf := new(bytes.Buffer)
  216. data := PingPayload{1, 1, 1}
  217. expectedBytes := []byte{
  218. 0, 3, // First two bytes encode the length.
  219. 1, 1, 1, // The actual data.
  220. }
  221. err := WritePingPayload(buf, data)
  222. require.NoError(t, err)
  223. require.Equal(t, expectedBytes, buf.Bytes())
  224. }
  225. func TestWritePongPayload(t *testing.T) {
  226. buf := new(bytes.Buffer)
  227. data := PongPayload{1, 1, 1}
  228. expectedBytes := []byte{
  229. 0, 3, // First two bytes encode the length.
  230. 1, 1, 1, // The actual data.
  231. }
  232. err := WritePongPayload(buf, data)
  233. require.NoError(t, err)
  234. require.Equal(t, expectedBytes, buf.Bytes())
  235. }
  236. func TestWriteErrorData(t *testing.T) {
  237. buf := new(bytes.Buffer)
  238. data := ErrorData{1, 1, 1}
  239. expectedBytes := []byte{
  240. 0, 3, // First two bytes encode the length.
  241. 1, 1, 1, // The actual data.
  242. }
  243. err := WriteErrorData(buf, data)
  244. require.NoError(t, err)
  245. require.Equal(t, expectedBytes, buf.Bytes())
  246. }
  247. func TestWriteOpaqueReason(t *testing.T) {
  248. buf := new(bytes.Buffer)
  249. data := OpaqueReason{1, 1, 1}
  250. expectedBytes := []byte{
  251. 0, 3, // First two bytes encode the length.
  252. 1, 1, 1, // The actual data.
  253. }
  254. err := WriteOpaqueReason(buf, data)
  255. require.NoError(t, err)
  256. require.Equal(t, expectedBytes, buf.Bytes())
  257. }
  258. func TestWriteBool(t *testing.T) {
  259. buf := new(bytes.Buffer)
  260. // Test write true.
  261. data := true
  262. expectedBytes := []byte{1}
  263. err := WriteBool(buf, data)
  264. require.NoError(t, err)
  265. require.Equal(t, expectedBytes, buf.Bytes())
  266. // Test write false.
  267. data = false
  268. expectedBytes = append(expectedBytes, 0)
  269. err = WriteBool(buf, data)
  270. require.NoError(t, err)
  271. require.Equal(t, expectedBytes, buf.Bytes())
  272. }
  273. func TestWritePkScript(t *testing.T) {
  274. buf := new(bytes.Buffer)
  275. // Write a very long script to check the error is returned as expected.
  276. script := PkScript{}
  277. zeros := [35]byte{}
  278. script = append(script, zeros[:]...)
  279. err := WritePkScript(buf, script)
  280. require.Equal(t, ErrPkScriptTooLong, err)
  281. data := PkScript{1, 1, 1}
  282. expectedBytes := []byte{
  283. 3, // First byte encodes the length.
  284. 1, 1, 1, // The actual data.
  285. }
  286. err = WritePkScript(buf, data)
  287. require.NoError(t, err)
  288. require.Equal(t, expectedBytes, buf.Bytes())
  289. }
  290. func TestWriteOutPoint(t *testing.T) {
  291. buf := new(bytes.Buffer)
  292. // Create an outpoint with very large index to check the error is
  293. // returned as expected.
  294. outpointWrong := wire.OutPoint{Index: math.MaxUint16 + 1}
  295. err := WriteOutPoint(buf, outpointWrong)
  296. require.Equal(t, ErrOutpointIndexTooBig(outpointWrong.Index), err)
  297. // Now check the normal write succeeds.
  298. hash := chainhash.Hash{1}
  299. data := wire.OutPoint{Index: 2, Hash: hash}
  300. expectedBytes := []byte{}
  301. expectedBytes = append(expectedBytes, hash[:]...)
  302. expectedBytes = append(expectedBytes, []byte{0, 2}...)
  303. err = WriteOutPoint(buf, data)
  304. require.NoError(t, err)
  305. require.Equal(t, expectedBytes, buf.Bytes())
  306. }
  307. func TestWriteTCPAddr(t *testing.T) {
  308. buf := new(bytes.Buffer)
  309. testCases := []struct {
  310. name string
  311. addr *net.TCPAddr
  312. expectedErr error
  313. expectedBytes []byte
  314. }{
  315. {
  316. // Check that the error is returned when nil address is
  317. // used.
  318. name: "nil address err",
  319. addr: nil,
  320. expectedErr: ErrNilTCPAddress,
  321. expectedBytes: nil,
  322. },
  323. {
  324. // Check write IPv4.
  325. name: "write ipv4",
  326. addr: &net.TCPAddr{
  327. IP: net.IP{127, 0, 0, 1},
  328. Port: 8080,
  329. },
  330. expectedErr: nil,
  331. expectedBytes: []byte{
  332. 0x1, // The addressType.
  333. 0x7f, 0x0, 0x0, 0x1, // The IP.
  334. 0x1f, 0x90, // The port (31 * 256 + 144).
  335. },
  336. },
  337. {
  338. // Check write IPv6.
  339. name: "write ipv6",
  340. addr: &net.TCPAddr{
  341. IP: net.IP{
  342. 1, 1, 1, 1, 1, 1, 1, 1,
  343. 1, 1, 1, 1, 1, 1, 1, 1,
  344. },
  345. Port: 8080,
  346. },
  347. expectedErr: nil,
  348. expectedBytes: []byte{
  349. 0x2, // The addressType.
  350. // The IP.
  351. 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
  352. 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
  353. 0x1f, 0x90, // The port (31 * 256 + 144).
  354. },
  355. },
  356. }
  357. for _, tc := range testCases {
  358. tc := tc
  359. t.Run(tc.name, func(t *testing.T) {
  360. oldLen := buf.Len()
  361. err := WriteTCPAddr(buf, tc.addr)
  362. require.Equal(t, tc.expectedErr, err)
  363. bytesWritten := buf.Bytes()[oldLen:buf.Len()]
  364. require.Equal(t, tc.expectedBytes, bytesWritten)
  365. })
  366. }
  367. }
  368. func TestWriteOnionAddr(t *testing.T) {
  369. buf := new(bytes.Buffer)
  370. testCases := []struct {
  371. name string
  372. addr *tor.OnionAddr
  373. expectedErr error
  374. expectedBytes []byte
  375. }{
  376. {
  377. // Check that the error is returned when nil address is
  378. // used.
  379. name: "nil address err",
  380. addr: nil,
  381. expectedErr: ErrNilOnionAddress,
  382. expectedBytes: nil,
  383. },
  384. {
  385. // Check the error is returned when an invalid onion
  386. // address is used.
  387. name: "wrong onion service length",
  388. addr: &tor.OnionAddr{OnionService: "wrong"},
  389. expectedErr: ErrUnknownServiceLength,
  390. expectedBytes: nil,
  391. },
  392. {
  393. // Check when the address has invalid base32 encoding,
  394. // the error is returned.
  395. name: "invalid base32 encoding",
  396. addr: &tor.OnionAddr{
  397. OnionService: "1234567890123456.onion",
  398. },
  399. expectedErr: base32.CorruptInputError(0),
  400. expectedBytes: nil,
  401. },
  402. {
  403. // Check write onion v2.
  404. name: "onion address v2",
  405. addr: &tor.OnionAddr{
  406. OnionService: "abcdefghijklmnop.onion",
  407. Port: 9065,
  408. },
  409. expectedErr: nil,
  410. expectedBytes: []byte{
  411. 0x3, // The descriptor.
  412. 0x0, 0x44, 0x32, 0x14, 0xc7, // The host.
  413. 0x42, 0x54, 0xb6, 0x35, 0xcf,
  414. 0x23, 0x69, // The port.
  415. },
  416. },
  417. {
  418. // Check write onion v3.
  419. name: "onion address v3",
  420. addr: &tor.OnionAddr{
  421. OnionService: "abcdefghij" +
  422. "abcdefghijabcdefghij" +
  423. "abcdefghijabcdefghij" +
  424. "234567.onion",
  425. Port: 9065,
  426. },
  427. expectedErr: nil,
  428. expectedBytes: []byte{
  429. 0x4, // The descriptor.
  430. 0x0, 0x44, 0x32, 0x14, 0xc7, 0x42, 0x40,
  431. 0x11, 0xc, 0x85, 0x31, 0xd0, 0x90, 0x4,
  432. 0x43, 0x21, 0x4c, 0x74, 0x24, 0x1, 0x10,
  433. 0xc8, 0x53, 0x1d, 0x9, 0x0, 0x44, 0x32,
  434. 0x14, 0xc7, 0x42, 0x75, 0xbe, 0x77, 0xdf,
  435. 0x23, 0x69, // The port.
  436. },
  437. },
  438. }
  439. for _, tc := range testCases {
  440. tc := tc
  441. t.Run(tc.name, func(t *testing.T) {
  442. oldLen := buf.Len()
  443. err := WriteOnionAddr(buf, tc.addr)
  444. require.Equal(t, tc.expectedErr, err)
  445. bytesWritten := buf.Bytes()[oldLen:buf.Len()]
  446. require.Equal(t, tc.expectedBytes, bytesWritten)
  447. })
  448. }
  449. }
  450. func TestWriteNetAddrs(t *testing.T) {
  451. buf := new(bytes.Buffer)
  452. tcpAddr := &net.TCPAddr{
  453. IP: net.IP{127, 0, 0, 1},
  454. Port: 8080,
  455. }
  456. onionAddr := &tor.OnionAddr{
  457. OnionService: "abcdefghijklmnop.onion",
  458. Port: 9065,
  459. }
  460. testCases := []struct {
  461. name string
  462. addr []net.Addr
  463. expectedErr error
  464. expectedBytes []byte
  465. }{
  466. {
  467. // Check that the error is returned when nil address is
  468. // used.
  469. name: "nil address err",
  470. addr: []net.Addr{nil, tcpAddr, onionAddr},
  471. expectedErr: ErrNilNetAddress,
  472. expectedBytes: nil,
  473. },
  474. {
  475. // Check empty address slice.
  476. name: "empty address slice",
  477. addr: []net.Addr{},
  478. expectedErr: nil,
  479. // Use two bytes to encode the address size.
  480. expectedBytes: []byte{0, 0},
  481. },
  482. {
  483. // Check a successful writes of a slice of addresses.
  484. name: "two addresses",
  485. addr: []net.Addr{tcpAddr, onionAddr},
  486. expectedErr: nil,
  487. expectedBytes: []byte{
  488. // 7 bytes for TCP and 13 bytes for onion.
  489. 0x0, 0x14,
  490. // TCP address.
  491. 0x1, 0x7f, 0x0, 0x0, 0x1, 0x1f, 0x90,
  492. // Onion address.
  493. 0x3, 0x0, 0x44, 0x32, 0x14, 0xc7, 0x42,
  494. 0x54, 0xb6, 0x35, 0xcf, 0x23, 0x69,
  495. },
  496. },
  497. }
  498. for _, tc := range testCases {
  499. tc := tc
  500. t.Run(tc.name, func(t *testing.T) {
  501. oldLen := buf.Len()
  502. err := WriteNetAddrs(buf, tc.addr)
  503. require.Equal(t, tc.expectedErr, err)
  504. bytesWritten := buf.Bytes()[oldLen:buf.Len()]
  505. require.Equal(t, tc.expectedBytes, bytesWritten)
  506. })
  507. }
  508. }