decred.org/dcrdex@v1.0.5/dex/msgjson/msg_test.go (about) 1 package msgjson 2 3 import ( 4 "bytes" 5 "encoding/hex" 6 "encoding/json" 7 "errors" 8 "math/rand" 9 "strings" 10 "testing" 11 12 "decred.org/dcrdex/server/account" 13 ) 14 15 func TestMessageUnmarshal(t *testing.T) { 16 // Test null payload handling. NO error. 17 msg := Message{ 18 Payload: []byte(`null`), 19 } 20 21 type Payload struct{} 22 23 payload := new(Payload) 24 err := msg.Unmarshal(payload) // *Payload 25 if err != nil { 26 t.Errorf("expected no error, got %v", err) 27 } 28 if payload == nil { 29 t.Errorf("expected payload to not be nil") 30 } 31 32 payload = new(Payload) 33 err = msg.Unmarshal(&payload) // **Payload 34 if err != nil { 35 t.Errorf("expected no error, got %v", err) 36 } 37 if payload != nil { 38 t.Errorf("expected payload to be nil") 39 } 40 } 41 42 func TestMessageResponse(t *testing.T) { 43 // Test null payload, expecting errNullRespPayload. 44 msg := Message{ 45 Type: Response, 46 Payload: []byte(`null`), 47 } 48 49 respPayload, err := msg.Response() 50 if !errors.Is(err, errNullRespPayload) { 51 t.Fatalf("expected a errNullRespPayload, got %v", err) 52 } 53 if respPayload != nil { 54 t.Errorf("response payload should have been nil") 55 } 56 57 // Test bad/empty json, expecting "unexpected end of JSON input". 58 msg.Payload = []byte(``) 59 respPayload, err = msg.Response() 60 const wantErrStr = "unexpected end of JSON input" 61 if err == nil || !strings.Contains(err.Error(), wantErrStr) { 62 t.Fatalf("expected error with %q, got %q", wantErrStr, err) 63 } 64 if respPayload != nil { 65 t.Errorf("response payload should have been nil") 66 } 67 } 68 69 func TestMatch(t *testing.T) { 70 // serialization: orderid (32) + matchid (8) + qty (8) + rate (8) 71 // + address (varies) 72 oid, _ := hex.DecodeString("2219c5f3a03407c87211748c884404e2f466cba19616faca1cda0010ca5db0d3") 73 mid, _ := hex.DecodeString("4969784b00a59dd0340952c9b8f52840fbb32e9b51d4f6e18cbec7f50c8a3ed7") 74 match := &Match{ 75 OrderID: oid, 76 MatchID: mid, 77 Quantity: 5e8, 78 Rate: uint64(2e8), 79 ServerTime: 1585043380123, 80 Address: "DcqXswjTPnUcd4FRCkX4vRJxmVtfgGVa5ui", 81 FeeRateBase: 65536 + 255, 82 FeeRateQuote: (1 << 32) + 256 + 1, 83 } 84 exp := []byte{ 85 // Order ID 32 bytes 86 0x22, 0x19, 0xc5, 0xf3, 0xa0, 0x34, 0x07, 0xc8, 0x72, 0x11, 0x74, 0x8c, 0x88, 87 0x44, 0x04, 0xe2, 0xf4, 0x66, 0xcb, 0xa1, 0x96, 0x16, 0xfa, 0xca, 0x1c, 0xda, 88 0x00, 0x10, 0xca, 0x5d, 0xb0, 0xd3, 89 // Match ID 32 bytes 90 0x49, 0x69, 0x78, 0x4b, 0x00, 0xa5, 0x9d, 0xd0, 0x34, 0x09, 0x52, 0xc9, 0xb8, 91 0xf5, 0x28, 0x40, 0xfb, 0xb3, 0x2e, 0x9b, 0x51, 0xd4, 0xf6, 0xe1, 0x8c, 0xbe, 92 0xc7, 0xf5, 0x0c, 0x8a, 0x3e, 0xd7, 93 // quantity 8 bytes 94 0x00, 0x00, 0x00, 0x00, 0x1d, 0xcd, 0x65, 0x00, 95 // rate 8 bytes 96 0x00, 0x00, 0x00, 0x00, 0x0b, 0xeb, 0xc2, 0x00, 97 // timestamp 8 bytes 98 0x00, 0x00, 0x01, 0x71, 0x0b, 0xf2, 0x97, 0x9b, 99 // address - utf-8 encoding 100 0x44, 0x63, 0x71, 0x58, 0x73, 0x77, 0x6a, 0x54, 0x50, 0x6e, 0x55, 0x63, 0x64, 101 0x34, 0x46, 0x52, 0x43, 0x6b, 0x58, 0x34, 0x76, 0x52, 0x4a, 0x78, 0x6d, 0x56, 102 0x74, 0x66, 0x67, 0x47, 0x56, 0x61, 0x35, 0x75, 0x69, 103 // base fee rate 8 bytes 104 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0xff, 105 // quote fee rate 8 bytes 106 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x1, 0x1, 107 } 108 109 b := match.Serialize() 110 if !bytes.Equal(b, exp) { 111 t.Fatalf("unexpected serialization. Wanted %x, got %x", exp, b) 112 } 113 114 matchB, err := json.Marshal(match) 115 if err != nil { 116 t.Fatalf("marshal error: %v", err) 117 } 118 119 var matchBack Match 120 err = json.Unmarshal(matchB, &matchBack) 121 if err != nil { 122 t.Fatalf("unmarshal error: %v", err) 123 } 124 125 if !bytes.Equal(matchBack.MatchID, match.MatchID) { 126 t.Fatal(matchBack.MatchID, match.MatchID) 127 } 128 if !bytes.Equal(matchBack.OrderID, match.OrderID) { 129 t.Fatal(matchBack.OrderID, match.OrderID) 130 } 131 if matchBack.Quantity != match.Quantity { 132 t.Fatal(matchBack.Quantity, match.Quantity) 133 } 134 if matchBack.Rate != match.Rate { 135 t.Fatal(matchBack.Rate, match.Rate) 136 } 137 if matchBack.ServerTime != match.ServerTime { 138 t.Fatal(matchBack.ServerTime, match.ServerTime) 139 } 140 if matchBack.Address != match.Address { 141 t.Fatal(matchBack.Address, match.Address) 142 } 143 } 144 145 func TestInit(t *testing.T) { 146 // serialization: orderid (32) + matchid (32) + txid (probably 64) + vout (4) 147 // + contract (97 ish) 148 oid, _ := hex.DecodeString("ceb09afa675cee31c0f858b94c81bd1a4c2af8c5947d13e544eef772381f2c8d") 149 mid, _ := hex.DecodeString("7c6b44735e303585d644c713fe0e95897e7e8ba2b9bba98d6d61b70006d3d58c") 150 coinid, _ := hex.DecodeString("c3161033de096fd74d9051ff0bd99e359de35080a3511081ed035f541b850d4300000005") 151 contract, _ := hex.DecodeString("caf8d277f80f71e4") 152 init := &Init{ 153 OrderID: oid, 154 MatchID: mid, 155 CoinID: coinid, 156 Contract: contract, 157 } 158 159 exp := []byte{ 160 // Order ID 32 bytes 161 0xce, 0xb0, 0x9a, 0xfa, 0x67, 0x5c, 0xee, 0x31, 0xc0, 0xf8, 0x58, 0xb9, 162 0x4c, 0x81, 0xbd, 0x1a, 0x4c, 0x2a, 0xf8, 0xc5, 0x94, 0x7d, 0x13, 0xe5, 163 0x44, 0xee, 0xf7, 0x72, 0x38, 0x1f, 0x2c, 0x8d, 164 // Match ID 32 bytes 165 0x7c, 0x6b, 0x44, 0x73, 0x5e, 0x30, 0x35, 0x85, 0xd6, 0x44, 0xc7, 0x13, 166 0xfe, 0x0e, 0x95, 0x89, 0x7e, 0x7e, 0x8b, 0xa2, 0xb9, 0xbb, 0xa9, 0x8d, 167 0x6d, 0x61, 0xb7, 0x00, 0x06, 0xd3, 0xd5, 0x8c, 168 // Coin ID 36 bytes 169 0xc3, 0x16, 0x10, 0x33, 0xde, 0x09, 0x6f, 0xd7, 0x4d, 0x90, 0x51, 0xff, 170 0x0b, 0xd9, 0x9e, 0x35, 0x9d, 0xe3, 0x50, 0x80, 0xa3, 0x51, 0x10, 0x81, 171 0xed, 0x03, 0x5f, 0x54, 0x1b, 0x85, 0x0d, 0x43, 0x00, 0x00, 0x00, 0x05, 172 // Contract 8 bytes (shortened for testing) 173 0xca, 0xf8, 0xd2, 0x77, 0xf8, 0x0f, 0x71, 0xe4, 174 } 175 b := init.Serialize() 176 if !bytes.Equal(b, exp) { 177 t.Fatalf("unexpected serialization. Wanted %x, got %x", exp, b) 178 } 179 180 initB, err := json.Marshal(init) 181 if err != nil { 182 t.Fatalf("marshal error: %v", err) 183 } 184 185 var initBack Init 186 err = json.Unmarshal(initB, &initBack) 187 if err != nil { 188 t.Fatalf("unmarshal error: %v", err) 189 } 190 191 if !bytes.Equal(initBack.MatchID, init.MatchID) { 192 t.Fatal(initBack.MatchID, init.MatchID) 193 } 194 if !bytes.Equal(initBack.OrderID, init.OrderID) { 195 t.Fatal(initBack.OrderID, init.OrderID) 196 } 197 if !bytes.Equal(initBack.CoinID, init.CoinID) { 198 t.Fatal(initBack.CoinID, init.CoinID) 199 } 200 if !bytes.Equal(initBack.Contract, init.Contract) { 201 t.Fatal(initBack.Contract, init.Contract) 202 } 203 } 204 205 func TestAudit(t *testing.T) { 206 // serialization: orderid (32) + matchid (32) + time (8) + coin ID (36) 207 // + contract (97 ish) 208 oid, _ := hex.DecodeString("d6c752bb34d833b6e0eb4d114d690d044f8ab3f6de9defa08e9d7d237f670fe4") 209 mid, _ := hex.DecodeString("79f84ef6c60e72edd305047c015d7b7ade64525a301fdac136976f05edb6172b") 210 coinID, _ := hex.DecodeString("3cdabd9bd62dfbd7d8b020d5de4e643b439886f4b0dc86cb8a56dff8e61c5ec333487a97") 211 contract, _ := hex.DecodeString("fc99f576f8e0e5dc") 212 audit := &Audit{ 213 OrderID: oid, 214 MatchID: mid, 215 Time: 1570705920, 216 CoinID: coinID, 217 Contract: contract, 218 } 219 220 exp := []byte{ 221 // Order ID 32 bytes 222 0xd6, 0xc7, 0x52, 0xbb, 0x34, 0xd8, 0x33, 0xb6, 0xe0, 0xeb, 0x4d, 0x11, 223 0x4d, 0x69, 0x0d, 0x04, 0x4f, 0x8a, 0xb3, 0xf6, 0xde, 0x9d, 0xef, 0xa0, 224 0x8e, 0x9d, 0x7d, 0x23, 0x7f, 0x67, 0x0f, 0xe4, 225 // Match ID 32 bytes 226 0x79, 0xf8, 0x4e, 0xf6, 0xc6, 0x0e, 0x72, 0xed, 0xd3, 0x05, 0x04, 0x7c, 227 0x01, 0x5d, 0x7b, 0x7a, 0xde, 0x64, 0x52, 0x5a, 0x30, 0x1f, 0xda, 0xc1, 228 0x36, 0x97, 0x6f, 0x05, 0xed, 0xb6, 0x17, 0x2b, 229 // Timestamp 8 bytes 230 0x00, 0x00, 0x00, 0x00, 0x5d, 0x9f, 0x12, 0x00, 231 // Coin ID 232 0x3c, 0xda, 0xbd, 0x9b, 0xd6, 0x2d, 0xfb, 0xd7, 0xd8, 0xb0, 0x20, 0xd5, 233 0xde, 0x4e, 0x64, 0x3b, 0x43, 0x98, 0x86, 0xf4, 0xb0, 0xdc, 0x86, 0xcb, 234 0x8a, 0x56, 0xdf, 0xf8, 0xe6, 0x1c, 0x5e, 0xc3, 0x33, 0x48, 0x7a, 0x97, 235 // Contract 8 bytes (shortened for testing) 236 0xfc, 0x99, 0xf5, 0x76, 0xf8, 0xe0, 0xe5, 0xdc, 237 } 238 239 b := audit.Serialize() 240 if !bytes.Equal(b, exp) { 241 t.Fatalf("unexpected serialization. Wanted %x, got %x", exp, b) 242 } 243 244 auditB, err := json.Marshal(audit) 245 if err != nil { 246 t.Fatalf("marshal error: %v", err) 247 } 248 249 var auditBack Audit 250 err = json.Unmarshal(auditB, &auditBack) 251 if err != nil { 252 t.Fatalf("unmarshal error: %v", err) 253 } 254 255 if !bytes.Equal(auditBack.MatchID, audit.MatchID) { 256 t.Fatal(auditBack.MatchID, audit.MatchID) 257 } 258 if !bytes.Equal(auditBack.OrderID, audit.OrderID) { 259 t.Fatal(auditBack.OrderID, audit.OrderID) 260 } 261 if auditBack.Time != audit.Time { 262 t.Fatal(auditBack.Time, audit.Time) 263 } 264 if !bytes.Equal(auditBack.Contract, audit.Contract) { 265 t.Fatal(auditBack.Contract, audit.Contract) 266 } 267 } 268 269 func TestRevokeMatch(t *testing.T) { 270 // serialization: order id (32) + match id (32) 271 oid, _ := hex.DecodeString("47b903b6e71a1fff3ec1be25b23228bf2e8682b1502dc451f7a9aa32556123f2") 272 mid, _ := hex.DecodeString("be218305e71b07a11c59c1b6c3ad3cf6ad4ed7582da8c639b87188aa95795c16") 273 revoke := &RevokeMatch{ 274 OrderID: oid, 275 MatchID: mid, 276 } 277 278 exp := []byte{ 279 // Order ID 32 bytes 280 0x47, 0xb9, 0x03, 0xb6, 0xe7, 0x1a, 0x1f, 0xff, 0x3e, 0xc1, 0xbe, 0x25, 281 0xb2, 0x32, 0x28, 0xbf, 0x2e, 0x86, 0x82, 0xb1, 0x50, 0x2d, 0xc4, 0x51, 282 0xf7, 0xa9, 0xaa, 0x32, 0x55, 0x61, 0x23, 0xf2, 283 // Match ID 32 bytes 284 0xbe, 0x21, 0x83, 0x05, 0xe7, 0x1b, 0x07, 0xa1, 0x1c, 0x59, 0xc1, 0xb6, 285 0xc3, 0xad, 0x3c, 0xf6, 0xad, 0x4e, 0xd7, 0x58, 0x2d, 0xa8, 0xc6, 0x39, 286 0xb8, 0x71, 0x88, 0xaa, 0x95, 0x79, 0x5c, 0x16, 287 } 288 289 b := revoke.Serialize() 290 if !bytes.Equal(b, exp) { 291 t.Fatalf("unexpected serialization. Wanted %x, got %x", exp, b) 292 } 293 294 revB, err := json.Marshal(revoke) 295 if err != nil { 296 t.Fatalf("marshal error: %v", err) 297 } 298 299 var revokeBack RevokeMatch 300 err = json.Unmarshal(revB, &revokeBack) 301 if err != nil { 302 t.Fatalf("unmarshal error: %v", err) 303 } 304 305 if !bytes.Equal(revokeBack.MatchID, revoke.MatchID) { 306 t.Fatal(revokeBack.MatchID, revoke.MatchID) 307 } 308 if !bytes.Equal(revokeBack.OrderID, revoke.OrderID) { 309 t.Fatal(revokeBack.OrderID, revoke.OrderID) 310 } 311 } 312 313 func TestRedeem(t *testing.T) { 314 // Redeem serialization is orderid (32) + matchid (32) + coin ID (36) + 315 // secret (32) = 132 316 oid, _ := hex.DecodeString("ee17139af2d86bd6052829389c0531f71042ed0b0539e617213a9a7151215a1b") 317 mid, _ := hex.DecodeString("6ea1227b03d7bf05ce1e23f3edf57368f69ba9ee0cc069f09ab0952a36d964c5") 318 coinid, _ := hex.DecodeString("28cb86e678f647cc88da734eed11286dab18b8483feb04580e3cbc90555a004700000005") 319 secret, _ := hex.DecodeString("f1df467afb1e0803cefa25e76cf00e07a99416087f6c9d10921bbbb55be5ded9") 320 redeem := &Redeem{ 321 OrderID: oid, 322 MatchID: mid, 323 CoinID: coinid, 324 Secret: secret, 325 } 326 327 exp := []byte{ 328 // Order ID 32 bytes 329 0xee, 0x17, 0x13, 0x9a, 0xf2, 0xd8, 0x6b, 0xd6, 0x05, 0x28, 0x29, 0x38, 330 0x9c, 0x05, 0x31, 0xf7, 0x10, 0x42, 0xed, 0x0b, 0x05, 0x39, 0xe6, 0x17, 331 0x21, 0x3a, 0x9a, 0x71, 0x51, 0x21, 0x5a, 0x1b, 332 // Match ID 32 bytes 333 0x6e, 0xa1, 0x22, 0x7b, 0x03, 0xd7, 0xbf, 0x05, 0xce, 0x1e, 0x23, 0xf3, 334 0xed, 0xf5, 0x73, 0x68, 0xf6, 0x9b, 0xa9, 0xee, 0x0c, 0xc0, 0x69, 0xf0, 335 0x9a, 0xb0, 0x95, 0x2a, 0x36, 0xd9, 0x64, 0xc5, 336 // Coin ID, 36 Bytes 337 0x28, 0xcb, 0x86, 0xe6, 0x78, 0xf6, 0x47, 0xcc, 0x88, 0xda, 0x73, 0x4e, 338 0xed, 0x11, 0x28, 0x6d, 0xab, 0x18, 0xb8, 0x48, 0x3f, 0xeb, 0x04, 0x58, 339 0x0e, 0x3c, 0xbc, 0x90, 0x55, 0x5a, 0x00, 0x47, 0x00, 0x00, 0x00, 0x05, 340 // Secret 32 bytes 341 0xf1, 0xdf, 0x46, 0x7a, 0xfb, 0x1e, 0x08, 0x03, 0xce, 0xfa, 0x25, 0xe7, 342 0x6c, 0xf0, 0x0e, 0x07, 0xa9, 0x94, 0x16, 0x08, 0x7f, 0x6c, 0x9d, 0x10, 343 0x92, 0x1b, 0xbb, 0xb5, 0x5b, 0xe5, 0xde, 0xd9, 344 } 345 346 b := redeem.Serialize() 347 if !bytes.Equal(b, exp) { 348 t.Fatalf("unexpected serialization. Wanted %x, got %x", exp, b) 349 } 350 351 redeemB, err := json.Marshal(redeem) 352 if err != nil { 353 t.Fatalf("marshal error: %v", err) 354 } 355 356 var redeemBack Redeem 357 err = json.Unmarshal(redeemB, &redeemBack) 358 if err != nil { 359 t.Fatalf("unmarshal error: %v", err) 360 } 361 362 if !bytes.Equal(redeemBack.MatchID, redeem.MatchID) { 363 t.Fatal(redeemBack.MatchID, redeem.MatchID) 364 } 365 if !bytes.Equal(redeemBack.OrderID, redeem.OrderID) { 366 t.Fatal(redeemBack.OrderID, redeem.OrderID) 367 } 368 if !bytes.Equal(redeemBack.CoinID, redeem.CoinID) { 369 t.Fatal(redeemBack.CoinID, redeem.CoinID) 370 } 371 } 372 373 func TestRedemption(t *testing.T) { 374 // serialization: orderid (32) + matchid (32) + txid (probably 64) + vout (4) 375 // + timestamp (8) 376 oid, _ := hex.DecodeString("ee17139af2d86bd6052829389c0531f71042ed0b0539e617213a9a7151215a1b") 377 mid, _ := hex.DecodeString("6ea1227b03d7bf05ce1e23f3edf57368f69ba9ee0cc069f09ab0952a36d964c5") 378 coinid, _ := hex.DecodeString("28cb86e678f647cc88da734eed11286dab18b8483feb04580e3cbc90555a004700000005") 379 redeem := &Redemption{ 380 Redeem: Redeem{ 381 OrderID: oid, 382 MatchID: mid, 383 CoinID: coinid, 384 }, 385 Time: 1570706834, 386 } 387 388 exp := []byte{ 389 // Order ID 32 bytes 390 0xee, 0x17, 0x13, 0x9a, 0xf2, 0xd8, 0x6b, 0xd6, 0x05, 0x28, 0x29, 0x38, 391 0x9c, 0x05, 0x31, 0xf7, 0x10, 0x42, 0xed, 0x0b, 0x05, 0x39, 0xe6, 0x17, 392 0x21, 0x3a, 0x9a, 0x71, 0x51, 0x21, 0x5a, 0x1b, 393 // Match ID 32 bytes 394 0x6e, 0xa1, 0x22, 0x7b, 0x03, 0xd7, 0xbf, 0x05, 0xce, 0x1e, 0x23, 0xf3, 395 0xed, 0xf5, 0x73, 0x68, 0xf6, 0x9b, 0xa9, 0xee, 0x0c, 0xc0, 0x69, 0xf0, 396 0x9a, 0xb0, 0x95, 0x2a, 0x36, 0xd9, 0x64, 0xc5, 397 // Coin ID, 36 Bytes 398 0x28, 0xcb, 0x86, 0xe6, 0x78, 0xf6, 0x47, 0xcc, 0x88, 0xda, 0x73, 0x4e, 399 0xed, 0x11, 0x28, 0x6d, 0xab, 0x18, 0xb8, 0x48, 0x3f, 0xeb, 0x04, 0x58, 400 0x0e, 0x3c, 0xbc, 0x90, 0x55, 0x5a, 0x00, 0x47, 0x00, 0x00, 0x00, 0x05, 401 // Timestamp 8 bytes 402 0x00, 0x00, 0x00, 0x00, 0x5d, 0x9f, 0x15, 0x92, 403 } 404 405 b := redeem.Serialize() 406 if !bytes.Equal(b, exp) { 407 t.Fatalf("unexpected serialization. Wanted %x, got %x", exp, b) 408 } 409 410 redeemB, err := json.Marshal(redeem) 411 if err != nil { 412 t.Fatalf("marshal error: %v", err) 413 } 414 415 var redeemBack Redemption 416 err = json.Unmarshal(redeemB, &redeemBack) 417 if err != nil { 418 t.Fatalf("unmarshal error: %v", err) 419 } 420 421 if !bytes.Equal(redeemBack.MatchID, redeem.MatchID) { 422 t.Fatal(redeemBack.MatchID, redeem.MatchID) 423 } 424 if !bytes.Equal(redeemBack.OrderID, redeem.OrderID) { 425 t.Fatal(redeemBack.OrderID, redeem.OrderID) 426 } 427 if !bytes.Equal(redeemBack.CoinID, redeem.CoinID) { 428 t.Fatal(redeemBack.CoinID, redeem.CoinID) 429 } 430 if redeemBack.Time != redeem.Time { 431 t.Fatal(redeemBack.Time, redeem.Time) 432 } 433 } 434 435 func TestPrefix(t *testing.T) { 436 // serialization: account ID (32) + base asset (4) + quote asset (4) + 437 // order type (1), client time (8), server time (8) = 57 bytes 438 acctID, _ := hex.DecodeString("05bf0f2b97fa551375b9c92687f7a948a8f4a4237653a04e6b00c6f14c72fd1e") 439 commit := []byte{ 440 0xd9, 0x83, 0xec, 0xdf, 0x34, 0x0f, 0xd9, 0xaf, 0xda, 0xb8, 0x81, 441 0x8d, 0x5a, 0x29, 0x36, 0xe0, 0x71, 0xaf, 0x3c, 0xbb, 0x3d, 0xa8, 442 0xac, 0xf4, 0x38, 0xb6, 0xc2, 0x91, 0x65, 0xf2, 0x0d, 0x8d, 443 } 444 prefix := &Prefix{ 445 AccountID: acctID, 446 Base: 256, 447 Quote: 65536, 448 OrderType: 1, 449 ClientTime: 1571871297, 450 ServerTime: 1571871841, 451 Commit: commit, 452 } 453 454 exp := []byte{ 455 // Account ID 32 bytes 456 0x05, 0xbf, 0x0f, 0x2b, 0x97, 0xfa, 0x55, 0x13, 0x75, 0xb9, 0xc9, 0x26, 457 0x87, 0xf7, 0xa9, 0x48, 0xa8, 0xf4, 0xa4, 0x23, 0x76, 0x53, 0xa0, 0x4e, 458 0x6b, 0x00, 0xc6, 0xf1, 0x4c, 0x72, 0xfd, 0x1e, 459 // Base Asset 4 bytes 460 0x00, 0x00, 0x01, 0x00, 461 // Quote Asset 4 bytes 462 0x00, 0x01, 0x00, 0x00, 463 // Order Type 1 bytes 464 0x01, 465 // Client Time 8 bytes 466 0x00, 0x00, 0x00, 0x00, 0x5d, 0xb0, 0xda, 0x41, 467 // Server Time 8 bytes (zeros for client signature) 468 0x00, 0x00, 0x00, 0x00, 0x5d, 0xb0, 0xdc, 0x61, 469 // Commitment 470 0xd9, 0x83, 0xec, 0xdf, 0x34, 0x0f, 0xd9, 0xaf, 0xda, 0xb8, 0x81, 471 0x8d, 0x5a, 0x29, 0x36, 0xe0, 0x71, 0xaf, 0x3c, 0xbb, 0x3d, 0xa8, 472 0xac, 0xf4, 0x38, 0xb6, 0xc2, 0x91, 0x65, 0xf2, 0x0d, 0x8d, 473 } 474 475 b := prefix.Serialize() 476 if !bytes.Equal(b, exp) { 477 t.Fatalf("unexpected serialization. Wanted %x, got %x", exp, b) 478 } 479 480 prefixB, err := json.Marshal(prefix) 481 if err != nil { 482 t.Fatalf("marshal error: %v", err) 483 } 484 485 var prefixBack Prefix 486 err = json.Unmarshal(prefixB, &prefixBack) 487 if err != nil { 488 t.Fatalf("unmarshal error: %v", err) 489 } 490 if !bytes.Equal(prefixBack.AccountID, prefix.AccountID) { 491 t.Fatalf("wrong account id. wanted %d, got %d", prefix.AccountID, prefixBack.AccountID) 492 } 493 if prefixBack.Base != prefix.Base { 494 t.Fatalf("wrong base asset. wanted %d, got %d", prefix.Base, prefixBack.Base) 495 } 496 if prefixBack.Quote != prefix.Quote { 497 t.Fatalf("wrong quote asset. wanted %d, got %d", prefix.Quote, prefixBack.Quote) 498 } 499 if prefixBack.OrderType != prefix.OrderType { 500 t.Fatalf("wrong order type. wanted %d, got %d", prefix.OrderType, prefixBack.OrderType) 501 } 502 if prefixBack.ClientTime != prefix.ClientTime { 503 t.Fatalf("wrong client time. wanted %d, got %d", prefix.ClientTime, prefixBack.ClientTime) 504 } 505 if prefixBack.ServerTime != prefix.ServerTime { 506 t.Fatalf("wrong server time. wanted %d, got %d", prefix.ServerTime, prefixBack.ServerTime) 507 } 508 if !bytes.Equal(prefixBack.Commit, prefix.Commit) { 509 t.Fatalf("wrong commitment. wanted %d, got %d", prefix.Commit, prefixBack.Commit) 510 } 511 } 512 513 func TestTrade(t *testing.T) { 514 // serialization: coin count (1), coin IDs (36*count), side (1), qty (8) 515 // = 10 + 36*count 516 517 addr := "13DePXLAKNsFCSmgfrEsYm8G1aCVZdYvP9" 518 coin1 := randomCoin() 519 coin2 := randomCoin() 520 521 trade := &Trade{ 522 Side: 1, 523 Quantity: 600_000_000, 524 Coins: []*Coin{coin1, coin2}, 525 Address: addr, 526 } 527 528 // Coin count 529 b := trade.Serialize() 530 if b[0] != 0x02 { 531 t.Fatalf("coin count byte incorrect: %d", b[0]) 532 } 533 b = b[1:] 534 535 // first coin 536 cLen := len(coin1.ID) 537 if !bytes.Equal(b[:cLen], coin1.ID) { 538 t.Fatal(b[:cLen], coin1.ID) 539 } 540 b = b[cLen:] 541 542 // second coin 543 cLen = len(coin2.ID) 544 if !bytes.Equal(b[:cLen], coin2.ID) { 545 t.Fatal(b[:cLen], coin2.ID) 546 } 547 b = b[cLen:] 548 549 // side 550 if b[0] != 0x01 { 551 t.Fatalf("wrong side. wanted 1, got %d", b[0]) 552 } 553 b = b[1:] 554 555 qty := []byte{0x00, 0x00, 0x00, 0x00, 0x23, 0xc3, 0x46, 0x00} 556 if !bytes.Equal(b, qty) { 557 t.Fatal(b, qty) 558 } 559 } 560 561 func TestLimit(t *testing.T) { 562 // serialization: prefix (105) + trade (variable) + address (~35) 563 // = 140 + len(trade) 564 prefix := &Prefix{ 565 AccountID: randomBytes(32), 566 Base: 256, 567 Quote: 65536, 568 OrderType: 1, 569 ClientTime: 1571874397, 570 ServerTime: 1571874405, 571 Commit: randomBytes(32), 572 } 573 addr := "DsDePXLAKNsFCSmgfrEsYm8G1aCVZdYvP9" 574 coin1 := randomCoin() 575 coin2 := randomCoin() 576 trade := &Trade{ 577 Side: 1, 578 Quantity: 600_000_000, 579 Coins: []*Coin{coin1, coin2}, 580 Address: addr, 581 } 582 limit := &LimitOrder{ 583 Prefix: *prefix, 584 Trade: *trade, 585 Rate: 350_000_000, 586 TiF: 1, 587 } 588 589 b := limit.Serialize() 590 591 // Compare the prefix byte-for-byte and pop it from the front. 592 x := prefix.Serialize() 593 xLen := len(x) 594 if !bytes.Equal(b[:xLen], x) { 595 t.Fatal(x, b[:xLen]) 596 } 597 b = b[xLen:] 598 599 // Compare the trade byte-for-byte and pop it from the front. 600 x = trade.Serialize() 601 xLen = len(x) 602 if !bytes.Equal(b[:xLen], x) { 603 t.Fatal(x, b[:xLen]) 604 } 605 b = b[xLen:] 606 607 exp := []byte{ 608 // Rate 8 bytes 609 0x00, 0x00, 0x00, 0x00, 0x14, 0xdc, 0x93, 0x80, 610 // Time-in-force 1 byte 611 0x01, 612 // Address 35 bytes 613 0x44, 0x73, 0x44, 0x65, 0x50, 0x58, 0x4c, 0x41, 0x4b, 0x4e, 0x73, 0x46, 614 0x43, 0x53, 0x6d, 0x67, 0x66, 0x72, 0x45, 0x73, 0x59, 0x6d, 0x38, 0x47, 615 0x31, 0x61, 0x43, 0x56, 0x5a, 0x64, 0x59, 0x76, 0x50, 0x39, 616 } 617 if !bytes.Equal(exp, b) { 618 t.Fatal(exp, b) 619 } 620 621 limitB, err := json.Marshal(limit) 622 if err != nil { 623 t.Fatalf("marshal error: %v", err) 624 } 625 626 var limitBack LimitOrder 627 err = json.Unmarshal(limitB, &limitBack) 628 if err != nil { 629 t.Fatalf("unmarshal error: %v", err) 630 } 631 comparePrefix(t, &limitBack.Prefix, &limit.Prefix) 632 compareTrade(t, &limitBack.Trade, &limit.Trade) 633 if limitBack.Rate != limit.Rate { 634 t.Fatal(limitBack.Rate, limit.Rate) 635 } 636 if limitBack.TiF != limit.TiF { 637 t.Fatal(limitBack.TiF, limit.TiF) 638 } 639 } 640 641 func TestMarket(t *testing.T) { 642 // serialization: prefix (105) + trade (variable) + rate (8) 643 // + time-in-force (1) + address (~35) = 149 + len(trade) 644 prefix := &Prefix{ 645 AccountID: randomBytes(32), 646 Base: 256, 647 Quote: 65536, 648 OrderType: 1, 649 ClientTime: 1571874397, 650 ServerTime: 1571874405, 651 Commit: randomBytes(32), 652 } 653 addr := "16brznLu4ieZ6tToKfUgibD94UcqshGUE3" 654 coin1 := randomCoin() 655 coin2 := randomCoin() 656 trade := &Trade{ 657 Side: 1, 658 Quantity: 600_000_000, 659 Coins: []*Coin{coin1, coin2}, 660 Address: addr, 661 } 662 market := &MarketOrder{ 663 Prefix: *prefix, 664 Trade: *trade, 665 } 666 667 b := market.Serialize() 668 669 // Compare the prefix byte-for-byte and pop it from the front. 670 x := prefix.Serialize() 671 xLen := len(x) 672 if !bytes.Equal(b[:xLen], x) { 673 t.Fatal(x, b[:xLen]) 674 } 675 b = b[xLen:] 676 677 // Compare the trade data byte-for-byte and pop it from the front. 678 x = trade.Serialize() 679 xLen = len(x) 680 if !bytes.Equal(b[:xLen], x) { 681 t.Fatal(x, b[:xLen]) 682 } 683 b = b[xLen:] 684 685 // The only thing left should be the utf-8 encoded address. 686 addrBytes := []byte{ 687 0x31, 0x36, 0x62, 0x72, 0x7a, 0x6e, 0x4c, 0x75, 0x34, 0x69, 0x65, 0x5a, 688 0x36, 0x74, 0x54, 0x6f, 0x4b, 0x66, 0x55, 0x67, 0x69, 0x62, 0x44, 0x39, 689 0x34, 0x55, 0x63, 0x71, 0x73, 0x68, 0x47, 0x55, 0x45, 0x33, 690 } 691 if !bytes.Equal(b, addrBytes) { 692 t.Fatal(b, addrBytes) 693 } 694 695 marketB, err := json.Marshal(market) 696 if err != nil { 697 t.Fatalf("marshal error: %v", err) 698 } 699 700 var marketBack MarketOrder 701 err = json.Unmarshal(marketB, &marketBack) 702 if err != nil { 703 t.Fatalf("unmarshal error: %v", err) 704 } 705 706 comparePrefix(t, &marketBack.Prefix, &market.Prefix) 707 compareTrade(t, &marketBack.Trade, &market.Trade) 708 } 709 710 func TestCancel(t *testing.T) { 711 // serialization: prefix (105) + target id (32) = 137 712 prefix := &Prefix{ 713 AccountID: randomBytes(32), 714 Base: 256, 715 Quote: 65536, 716 OrderType: 1, 717 ClientTime: 1571874397, 718 ServerTime: 1571874405, 719 Commit: randomBytes(32), 720 } 721 targetID, _ := hex.DecodeString("a1f1b66916353b58dbb65562eb19731953b2f1215987a9d9137f0df3458637b7") 722 cancel := &CancelOrder{ 723 Prefix: *prefix, 724 TargetID: targetID, 725 } 726 727 b := cancel.Serialize() 728 729 // Compare the prefix byte-for-byte and pop it from the front. 730 x := prefix.Serialize() 731 xLen := len(x) 732 if !bytes.Equal(x, b[:xLen]) { 733 t.Fatal(x, b[:xLen]) 734 } 735 b = b[xLen:] 736 737 target := []byte{ 738 0xa1, 0xf1, 0xb6, 0x69, 0x16, 0x35, 0x3b, 0x58, 0xdb, 0xb6, 0x55, 0x62, 739 0xeb, 0x19, 0x73, 0x19, 0x53, 0xb2, 0xf1, 0x21, 0x59, 0x87, 0xa9, 0xd9, 740 0x13, 0x7f, 0x0d, 0xf3, 0x45, 0x86, 0x37, 0xb7, 741 } 742 if !bytes.Equal(b, target) { 743 t.Fatal(b, target) 744 } 745 746 cancelB, err := json.Marshal(cancel) 747 if err != nil { 748 t.Fatalf("marshal error: %v", err) 749 } 750 751 var cancelBack CancelOrder 752 err = json.Unmarshal(cancelB, &cancelBack) 753 if err != nil { 754 t.Fatalf("unmarshal error: %v", err) 755 } 756 757 comparePrefix(t, &cancelBack.Prefix, &cancel.Prefix) 758 if !bytes.Equal(cancelBack.TargetID, cancel.TargetID) { 759 t.Fatal(cancelBack.TargetID, cancel.TargetID) 760 } 761 } 762 763 func TestConnect(t *testing.T) { 764 // serialization: account ID (32) + api version (2) + timestamp (8) = 42 bytes 765 acctID, _ := hex.DecodeString("14ae3cbc703587122d68ac6fa9194dfdc8466fb5dec9f47d2805374adff3e016") 766 connect := &Connect{ 767 AccountID: acctID, 768 APIVersion: uint16(1), 769 Time: uint64(1571575096), 770 } 771 772 exp := []byte{ 773 // Account ID 32 bytes 774 0x14, 0xae, 0x3c, 0xbc, 0x70, 0x35, 0x87, 0x12, 0x2d, 0x68, 0xac, 0x6f, 775 0xa9, 0x19, 0x4d, 0xfd, 0xc8, 0x46, 0x6f, 0xb5, 0xde, 0xc9, 0xf4, 0x7d, 776 0x28, 0x05, 0x37, 0x4a, 0xdf, 0xf3, 0xe0, 0x16, 777 // API Version 2 bytes 778 0x00, 0x01, 779 // Time 8 bytes 780 0x00, 0x00, 0x00, 0x00, 0x5d, 0xac, 0x55, 0x38, 781 } 782 783 b := connect.Serialize() 784 if !bytes.Equal(b, exp) { 785 t.Fatalf("unexpected serialization. Wanted %x, got %x", exp, b) 786 } 787 788 connectB, err := json.Marshal(connect) 789 if err != nil { 790 t.Fatalf("marshal error: %v", err) 791 } 792 793 var connectBack Connect 794 err = json.Unmarshal(connectB, &connectBack) 795 if err != nil { 796 t.Fatalf("unmarshal error: %v", err) 797 } 798 799 if !bytes.Equal(connectBack.AccountID, connect.AccountID) { 800 t.Fatal(connectBack.AccountID, connect.AccountID) 801 } 802 if connectBack.APIVersion != connect.APIVersion { 803 t.Fatal(connectBack.APIVersion, connect.APIVersion) 804 } 805 if connectBack.Time != connect.Time { 806 t.Fatal(connectBack.Time, connect.Time) 807 } 808 } 809 810 func TestPenalty(t *testing.T) { 811 // serialization: rule(1) + time (8) + duration (8) + details (variable, ~100) = 117 bytes 812 penalty := &Penalty{ 813 Rule: account.Rule(1), 814 Time: uint64(1598929305), 815 Details: "You may no longer trade. Leave your client running to finish pending trades.", 816 } 817 penaltyNote := &PenaltyNote{Penalty: penalty} 818 819 exp := []byte{ 820 // Rule 1 byte. 821 0x01, 822 // Time 8 bytes. 823 0x00, 0x00, 0x00, 0x00, 0x5f, 0x4d, 0xb9, 0x99, 824 // Details 76 bytes. 825 0x59, 0x6f, 0x75, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x6e, 0x6f, 826 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x20, 0x74, 0x72, 827 0x61, 0x64, 0x65, 0x2e, 0x20, 0x4c, 0x65, 0x61, 0x76, 0x65, 828 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x63, 0x6c, 0x69, 0x65, 829 0x6e, 0x74, 0x20, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 830 0x20, 0x74, 0x6f, 0x20, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 831 0x20, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 832 0x72, 0x61, 0x64, 0x65, 0x73, 0x2e, 833 } 834 835 b := penaltyNote.Serialize() 836 if !bytes.Equal(b, exp) { 837 t.Fatalf("unexpected serialization. Wanted %x, got %x", exp, b) 838 } 839 840 penaltyB, err := json.Marshal(penalty) 841 if err != nil { 842 t.Fatalf("marshal error: %v", err) 843 } 844 845 var penaltyBack Penalty 846 err = json.Unmarshal(penaltyB, &penaltyBack) 847 if err != nil { 848 t.Fatalf("unmarshal error: %v", err) 849 } 850 851 if penaltyBack.Rule != penalty.Rule { 852 t.Fatal(penaltyBack.Rule, penalty.Rule) 853 } 854 if penaltyBack.Time != penalty.Time { 855 t.Fatal(penaltyBack.Time, penalty.Time) 856 } 857 if penaltyBack.Details != penalty.Details { 858 t.Fatal(penaltyBack.Details, penalty.Details) 859 } 860 } 861 862 func TestRegister(t *testing.T) { 863 // serialization: pubkey (33) + time (8) = 41 864 pk, _ := hex.DecodeString("f06e5cf13fc6debb8b90776da6624991ba50a11e784efed53d0a81c3be98397982") 865 register := &Register{ 866 PubKey: pk, 867 Time: uint64(1571700077), 868 } 869 870 exp := []byte{ 871 // PubKey 33 bytes 872 0xf0, 0x6e, 0x5c, 0xf1, 0x3f, 0xc6, 0xde, 0xbb, 0x8b, 0x90, 0x77, 0x6d, 873 0xa6, 0x62, 0x49, 0x91, 0xba, 0x50, 0xa1, 0x1e, 0x78, 0x4e, 0xfe, 0xd5, 874 0x3d, 0x0a, 0x81, 0xc3, 0xbe, 0x98, 0x39, 0x79, 0x82, 875 // Time 8 bytes 876 0x00, 0x00, 0x00, 0x00, 0x5d, 0xae, 0x3d, 0x6d, 877 } 878 879 b := register.Serialize() 880 if !bytes.Equal(b, exp) { 881 t.Fatalf("unexpected serialization. Wanted %x, got %x", exp, b) 882 } 883 884 registerB, err := json.Marshal(register) 885 if err != nil { 886 t.Fatalf("marshal error: %v", err) 887 } 888 889 var registerBack Register 890 err = json.Unmarshal(registerB, ®isterBack) 891 if err != nil { 892 t.Fatalf("unmarshal error: %v", err) 893 } 894 895 if !bytes.Equal(registerBack.PubKey, register.PubKey) { 896 t.Fatal(registerBack.PubKey, register.PubKey) 897 } 898 if registerBack.Time != register.Time { 899 t.Fatal(registerBack.Time, register.Time) 900 } 901 } 902 903 func TestNotifyFee(t *testing.T) { 904 // serialization: account id (32) + txid (32) + vout (4) = 68 905 acctID, _ := hex.DecodeString("bd3faf7353b8fc40618527687b3ef99d00da480e354f2c4986479e2da626acf5") 906 coinid, _ := hex.DecodeString("51891f751b0dd987c0b8ff1703cd0dd3e2712847f4bdbc268c9656dc80d233c7") 907 notify := &NotifyFee{ 908 AccountID: acctID, 909 CoinID: coinid, 910 Time: 1571704611, 911 } 912 913 exp := []byte{ 914 // Account ID 32 bytes 915 0xbd, 0x3f, 0xaf, 0x73, 0x53, 0xb8, 0xfc, 0x40, 0x61, 0x85, 0x27, 0x68, 916 0x7b, 0x3e, 0xf9, 0x9d, 0x00, 0xda, 0x48, 0x0e, 0x35, 0x4f, 0x2c, 0x49, 917 0x86, 0x47, 0x9e, 0x2d, 0xa6, 0x26, 0xac, 0xf5, 918 // Tx ID 32 bytes 919 0x51, 0x89, 0x1f, 0x75, 0x1b, 0x0d, 0xd9, 0x87, 0xc0, 0xb8, 0xff, 0x17, 920 0x03, 0xcd, 0x0d, 0xd3, 0xe2, 0x71, 0x28, 0x47, 0xf4, 0xbd, 0xbc, 0x26, 921 0x8c, 0x96, 0x56, 0xdc, 0x80, 0xd2, 0x33, 0xc7, 922 // Time 8 bytes 923 0x00, 0x00, 0x00, 0x00, 0x5d, 0xae, 0x4f, 0x23, 924 } 925 926 b := notify.Serialize() 927 if !bytes.Equal(b, exp) { 928 t.Fatalf("unexpected serialization. Wanted %x, got %x", exp, b) 929 } 930 931 notifyB, err := json.Marshal(notify) 932 if err != nil { 933 t.Fatalf("marshal error: %v", err) 934 } 935 936 var notifyBack NotifyFee 937 err = json.Unmarshal(notifyB, ¬ifyBack) 938 if err != nil { 939 t.Fatalf("unmarshal error: %v", err) 940 } 941 942 if !bytes.Equal(notifyBack.AccountID, notify.AccountID) { 943 t.Fatal(notifyBack.AccountID, notify.AccountID) 944 } 945 if !bytes.Equal(notifyBack.CoinID, notify.CoinID) { 946 t.Fatal(notifyBack.CoinID, notify.CoinID) 947 } 948 if notifyBack.Time != notify.Time { 949 t.Fatal(notifyBack.Time, notify.Time) 950 } 951 } 952 953 func TestSignable(t *testing.T) { 954 sig := []byte{ 955 0x07, 0xad, 0x7f, 0x33, 0xc5, 0xb0, 0x13, 0xa1, 0xbb, 0xd6, 0xad, 0xc0, 956 0xd2, 0x16, 0xd8, 0x93, 0x8c, 0x73, 0x64, 0xe5, 0x6a, 0x17, 0x8c, 0x7a, 957 0x17, 0xa9, 0xe7, 0x47, 0xad, 0x55, 0xaf, 0xe6, 0x55, 0x2b, 0xb2, 0x76, 958 0xf8, 0x8e, 0x34, 0x2e, 0x56, 0xac, 0xaa, 0x8a, 0x52, 0x41, 0x2e, 0x51, 959 0x8b, 0x0f, 0xe6, 0xb2, 0x2a, 0x21, 0x77, 0x9a, 0x76, 0x99, 0xa5, 0xe5, 960 0x39, 0xa8, 0xa1, 0xdd, 0x1d, 0x49, 0x8b, 0xb0, 0x16, 0xf7, 0x18, 0x70, 961 } 962 s := Signature{} 963 s.SetSig(sig) 964 if !bytes.Equal(sig, s.SigBytes()) { 965 t.Fatalf("signatures not equal") 966 } 967 } 968 969 func TestBytes(t *testing.T) { 970 rawB := []byte{0xfc, 0xf6, 0xd9, 0xb9, 0xdb, 0x10, 0x4c, 0xc0, 0x13, 0x3a} 971 hexB := "fcf6d9b9db104cc0133a" 972 973 type byter struct { 974 B Bytes `json:"b"` 975 } 976 977 b := byter{} 978 js := `{"b":"` + hexB + `"}` 979 err := json.Unmarshal([]byte(js), &b) 980 if err != nil { 981 t.Fatalf("unmarshal error: %v", err) 982 } 983 984 if !bytes.Equal(rawB, b.B) { 985 t.Fatalf("unmarshalled Bytes not correct. wanted %x, got %x.", rawB, b.B) 986 } 987 988 marshalled, err := json.Marshal(b) 989 if err != nil { 990 t.Fatalf("marshal error: %v", err) 991 } 992 if string(marshalled) != js { 993 t.Fatalf("marshalled Bytes not correct. wanted %s, got %s", js, string(marshalled)) 994 } 995 996 fromHex, _ := hex.DecodeString(hexB) 997 if !bytes.Equal(rawB, fromHex) { 998 t.Fatalf("hex-constructed Bytes not correct. wanted %x, got %x.", rawB, fromHex) 999 } 1000 } 1001 1002 func TestDecodeMessage(t *testing.T) { 1003 msg, err := DecodeMessage([]byte(`{"type":1,"route":"testroute","id":5,"payload":10}`)) 1004 if err != nil { 1005 t.Fatalf("error decoding json message: %v", err) 1006 } 1007 if msg.Type != 1 { 1008 t.Fatalf("wrong message type. wanted 1, got %d", msg.Type) 1009 } 1010 if msg.Route != "testroute" { 1011 t.Fatalf("wrong message type. wanted 'testroute', got '%s'", msg.Route) 1012 } 1013 if msg.ID != 5 { 1014 t.Fatalf("wrong message type. wanted 5, got %d", msg.ID) 1015 } 1016 if string(msg.Payload) != "10" { 1017 t.Fatalf("wrong payload. wanted '10, got '%s'", string(msg.Payload)) 1018 } 1019 // Test invalid json 1020 _, err = DecodeMessage([]byte(`{"type":?}`)) 1021 if err == nil { 1022 t.Fatalf("no json decode error for invalid json") 1023 } 1024 } 1025 1026 func TestRespReq(t *testing.T) { 1027 // Test invalid json result. 1028 _, err := NewResponse(5, make(chan int), nil) 1029 if err == nil { 1030 t.Fatalf("no error for invalid json") 1031 } 1032 // Zero ID not valid. 1033 _, err = NewResponse(0, 10, nil) 1034 if err == nil { 1035 t.Fatalf("no error for id = 0") 1036 } 1037 msg, err := NewResponse(5, 10, nil) 1038 if err != nil { 1039 t.Fatalf("NewResponse error: %v", err) 1040 } 1041 if msg.ID != 5 { 1042 t.Fatalf("wrong message ID. wanted 5, got ") 1043 } 1044 resp, err := msg.Response() 1045 if err != nil { 1046 t.Fatalf("error getting response payload: %v", err) 1047 } 1048 if resp.Error != nil { 1049 t.Fatalf("unexpected error making success response") 1050 } 1051 if string(resp.Result) != "10" { 1052 t.Fatalf("unexpected result. wanted '10', got '%s'", string(resp.Result)) 1053 } 1054 1055 // Check error. 1056 msg, err = NewResponse(5, nil, NewError(15, "testmsg")) 1057 if err != nil { 1058 t.Fatalf("unexpected error making error response") 1059 } 1060 _, err = msg.Response() 1061 if err != nil { 1062 t.Fatalf("unexpected error getting error response payload: %v", err) 1063 } 1064 1065 // Test Requests 1066 _, err = NewRequest(5, "testroute", make(chan int)) 1067 if err == nil { 1068 t.Fatalf("no error for invalid json type request payload") 1069 } 1070 _, err = NewRequest(0, "testroute", 10) 1071 if err == nil { 1072 t.Fatalf("no error id = 0 request") 1073 } 1074 _, err = NewRequest(5, "", 10) 1075 if err == nil { 1076 t.Fatalf("no error for empty string route request") 1077 } 1078 msg, err = NewRequest(5, "testroute", 10) 1079 if err != nil { 1080 t.Fatalf("error for valid request payload: %v", err) 1081 } 1082 // A Request-type Message should error if trying to retrieve the 1083 // ResponsePayload 1084 _, err = msg.Response() 1085 if err == nil { 1086 t.Fatalf("no error when retrieving response payload from request-type message") 1087 } 1088 1089 // Test Notifications 1090 _, err = NewNotification("testroute", make(chan int)) 1091 if err == nil { 1092 t.Fatalf("no error for invalid json type notification payload") 1093 } 1094 _, err = NewNotification("", 10) 1095 if err == nil { 1096 t.Fatalf("no error for empty string route request") 1097 } 1098 _, err = NewNotification("testroute", 10) 1099 if err != nil { 1100 t.Fatalf("error for valid request payload: %v", err) 1101 } 1102 } 1103 1104 func comparePrefix(t *testing.T, p1, p2 *Prefix) { 1105 if !bytes.Equal(p1.AccountID, p2.AccountID) { 1106 t.Fatal(p1.AccountID, p2.AccountID) 1107 } 1108 if p1.Base != p2.Base { 1109 t.Fatal(p1.Base, p2.Base) 1110 } 1111 if p1.Quote != p2.Quote { 1112 t.Fatal(p1.Quote, p2.Quote) 1113 } 1114 if p1.OrderType != p2.OrderType { 1115 t.Fatal(p1.OrderType, p2.OrderType) 1116 } 1117 if p1.ClientTime != p2.ClientTime { 1118 t.Fatal(p1.ClientTime, p2.ClientTime) 1119 } 1120 if p1.ServerTime != p2.ServerTime { 1121 t.Fatal(p1.ServerTime, p2.ServerTime) 1122 } 1123 } 1124 1125 func compareTrade(t *testing.T, t1, t2 *Trade) { 1126 if t1.Side != t2.Side { 1127 t.Fatal(t1.Side, t2.Side) 1128 } 1129 if t1.Quantity != t2.Quantity { 1130 t.Fatal(t1.Quantity, t2.Quantity) 1131 } 1132 if len(t1.Coins) != 2 { 1133 t.Fatalf("wrong number of coins. expected 2 got %d", len(t1.Coins)) 1134 } 1135 if t1.Address != t2.Address { 1136 t.Fatal(t1.Address, t2.Address) 1137 } 1138 } 1139 1140 func randomBytes(len int) []byte { 1141 bytes := make([]byte, len) 1142 rand.Read(bytes) 1143 return bytes 1144 } 1145 1146 func randomCoin() *Coin { 1147 return &Coin{ 1148 ID: randomBytes(36), 1149 // the rest are not part of the serialized coins. 1150 PubKeys: []Bytes{randomBytes(33)}, 1151 Sigs: []Bytes{randomBytes(77)}, 1152 Redeem: randomBytes(25), 1153 } 1154 }