1// SPDX-License-Identifier: ISC 2// Copyright (c) 2014-2020 Bitmark Inc. 3// Use of this source code is governed by an ISC 4// license that can be found in the LICENSE file. 5 6package transactionrecord_test 7 8import ( 9 "bytes" 10 "encoding/json" 11 "reflect" 12 "testing" 13 14 "golang.org/x/crypto/ed25519" 15 16 "github.com/bitmark-inc/bitmarkd/currency" 17 "github.com/bitmark-inc/bitmarkd/fault" 18 "github.com/bitmark-inc/bitmarkd/merkle" 19 "github.com/bitmark-inc/bitmarkd/transactionrecord" 20 "github.com/bitmark-inc/bitmarkd/util" 21) 22 23// test the packing/unpacking of Bitmark transfer record 24// 25// transfer from issue 26// ensures that pack->unpack returns the same original value 27func TestPackBitmarkTransferCountersignedOne(t *testing.T) { 28 29 issuerAccount := makeAccount(issuer.publicKey) 30 ownerOneAccount := makeAccount(ownerOne.publicKey) 31 32 var link merkle.Digest 33 err := merkleDigestFromLE("79a67be2b3d313bd490363fb0d27901c46ed53d3f7b21f60d48bc42439b06084", &link) 34 if nil != err { 35 t.Fatalf("hex to link error: %s", err) 36 } 37 38 r := transactionrecord.BitmarkTransferCountersigned{ 39 Link: link, 40 Owner: ownerOneAccount, 41 } 42 43 expected := []byte{ 44 0x05, 0x20, 0x79, 0xa6, 0x7b, 0xe2, 0xb3, 0xd3, 45 0x13, 0xbd, 0x49, 0x03, 0x63, 0xfb, 0x0d, 0x27, 46 0x90, 0x1c, 0x46, 0xed, 0x53, 0xd3, 0xf7, 0xb2, 47 0x1f, 0x60, 0xd4, 0x8b, 0xc4, 0x24, 0x39, 0xb0, 48 0x60, 0x84, 0x00, 0x21, 0x13, 0x27, 0x64, 0x0e, 49 0x4a, 0xab, 0x92, 0xd8, 0x7b, 0x4a, 0x6a, 0x2f, 50 0x30, 0xb8, 0x81, 0xf4, 0x49, 0x29, 0xf8, 0x66, 51 0x04, 0x3a, 0x84, 0x1c, 0x38, 0x14, 0xb1, 0x66, 52 0xb8, 0x89, 0x44, 0xb0, 0x92, 53 } 54 55 expectedTxId := merkle.Digest{ 56 0x6e, 0x72, 0xbb, 0x9a, 0x58, 0x50, 0xcc, 0x28, 57 0x8e, 0x3c, 0x72, 0x6f, 0xbb, 0xe4, 0x33, 0xa0, 58 0xe0, 0x81, 0x78, 0xac, 0xde, 0x1c, 0x8c, 0xb0, 59 0x31, 0xa4, 0x36, 0x2d, 0x77, 0xa0, 0x4e, 0x09, 60 } 61 62 // manually sign the record and attach signature to "expected" 63 signature := ed25519.Sign(issuer.privateKey, expected) 64 r.Signature = signature 65 l := util.ToVarint64(uint64(len(signature))) 66 expected = append(expected, l...) 67 expected = append(expected, signature...) 68 69 // manually countersign the record and attach countersignature to "expected" 70 signature = ed25519.Sign(ownerOne.privateKey, expected) 71 r.Countersignature = signature 72 l = util.ToVarint64(uint64(len(signature))) 73 expected = append(expected, l...) 74 expected = append(expected, signature...) 75 76 // test the packer 77 packed, err := r.Pack(issuerAccount) 78 if nil != err { 79 t.Errorf("pack error: %s", err) 80 } 81 82 // if either of above fail we will have the message _without_ a signature 83 if !bytes.Equal(packed, expected) { 84 t.Errorf("pack record: %x expected: %x", packed, expected) 85 t.Errorf("*** GENERATED Packed:\n%s", util.FormatBytes("expected", packed)) 86 t.Fatal("fatal error") 87 } 88 89 t.Logf("Packed length: %d bytes", len(packed)) 90 91 // check txId 92 txId := packed.MakeLink() 93 94 if txId != expectedTxId { 95 t.Errorf("pack txId: %#v expected: %x", txId, expectedTxId) 96 t.Errorf("*** GENERATED txId:\n%s", util.FormatBytes("expectedTxId", txId[:])) 97 t.Fatal("fatal error") 98 } 99 100 // test the unpacker 101 unpacked, n, err := packed.Unpack(true) 102 if nil != err { 103 t.Fatalf("unpack error: %s", err) 104 } 105 if len(packed) != n { 106 t.Errorf("did not unpack all data: only used: %d of: %d bytes", n, len(packed)) 107 } 108 109 bmt, ok := unpacked.(*transactionrecord.BitmarkTransferCountersigned) 110 if !ok { 111 t.Fatalf("did not unpack to BitmarkTransferCountersigned") 112 } 113 114 // display a JSON version for information 115 item := struct { 116 TxId merkle.Digest 117 BitmarkTransferCountersigned *transactionrecord.BitmarkTransferCountersigned 118 }{ 119 txId, 120 bmt, 121 } 122 b, err := json.MarshalIndent(item, "", " ") 123 if nil != err { 124 t.Fatalf("json error: %s", err) 125 } 126 127 t.Logf("Bitmark Transfer: JSON: %s", b) 128 129 // check that structure is preserved through Pack/Unpack 130 // note reg is a pointer here 131 if !reflect.DeepEqual(r, *bmt) { 132 t.Fatalf("different, original: %v recovered: %v", r, *bmt) 133 } 134} 135 136// test the packing/unpacking of Bitmark transfer record 137// 138// test transfer to transfer 139// ensures that pack->unpack returns the same original value 140func TestPackBitmarkTransferCountersignedTwo(t *testing.T) { 141 142 ownerOneAccount := makeAccount(ownerOne.publicKey) 143 ownerTwoAccount := makeAccount(ownerTwo.publicKey) 144 145 var link merkle.Digest 146 err := merkleDigestFromLE("630c041cd1f586bcb9097e816189185c1e0379f67bbfc2f0626724f542047873", &link) 147 if nil != err { 148 t.Fatalf("hex to link error: %s", err) 149 } 150 151 r := transactionrecord.BitmarkTransferCountersigned{ 152 Link: link, 153 Escrow: &transactionrecord.Payment{ 154 Currency: currency.Bitcoin, 155 Address: "mnnemVbQECtikaGZPYux4dGHH3YZyCg4sq", 156 Amount: 250000, 157 }, 158 Owner: ownerTwoAccount, 159 } 160 161 expected := []byte{ 162 0x05, 0x20, 0x63, 0x0c, 0x04, 0x1c, 0xd1, 0xf5, 163 0x86, 0xbc, 0xb9, 0x09, 0x7e, 0x81, 0x61, 0x89, 164 0x18, 0x5c, 0x1e, 0x03, 0x79, 0xf6, 0x7b, 0xbf, 165 0xc2, 0xf0, 0x62, 0x67, 0x24, 0xf5, 0x42, 0x04, 166 0x78, 0x73, 0x01, 0x01, 0x22, 0x6d, 0x6e, 0x6e, 167 0x65, 0x6d, 0x56, 0x62, 0x51, 0x45, 0x43, 0x74, 168 0x69, 0x6b, 0x61, 0x47, 0x5a, 0x50, 0x59, 0x75, 169 0x78, 0x34, 0x64, 0x47, 0x48, 0x48, 0x33, 0x59, 170 0x5a, 0x79, 0x43, 0x67, 0x34, 0x73, 0x71, 0x90, 171 0xa1, 0x0f, 0x21, 0x13, 0xa1, 0x36, 0x32, 0xd5, 172 0x42, 0x5a, 0xed, 0x3a, 0x6b, 0x62, 0xe2, 0xbb, 173 0x6d, 0xe4, 0xc9, 0x59, 0x48, 0x41, 0xc1, 0x5b, 174 0x70, 0x15, 0x69, 0xec, 0x99, 0x99, 0xdc, 0x20, 175 0x1c, 0x35, 0xf7, 0xb3, 176 } 177 178 expectedTxId := merkle.Digest{ 179 0x2a, 0xf9, 0xd9, 0xf1, 0xbb, 0x8d, 0x8a, 0x54, 180 0x68, 0x55, 0x7c, 0x86, 0x97, 0x96, 0x01, 0x18, 181 0x48, 0x2c, 0x08, 0x6a, 0x76, 0xc1, 0xcb, 0xb0, 182 0x21, 0xf7, 0x3f, 0x4d, 0x27, 0x65, 0x37, 0x70, 183 } 184 185 // manually sign the record and attach signature to "expected" 186 signature := ed25519.Sign(ownerOne.privateKey, expected) 187 r.Signature = signature 188 l := util.ToVarint64(uint64(len(signature))) 189 expected = append(expected, l...) 190 expected = append(expected, signature...) 191 192 // manually countersign the record and attach countersignature to "expected" 193 signature = ed25519.Sign(ownerTwo.privateKey, expected) 194 r.Countersignature = signature 195 l = util.ToVarint64(uint64(len(signature))) 196 expected = append(expected, l...) 197 expected = append(expected, signature...) 198 199 // test the packer 200 packed, err := r.Pack(ownerOneAccount) 201 if nil != err { 202 t.Errorf("pack error: %s", err) 203 } 204 205 // if either of above fail we will have the message _without_ a signature 206 if !bytes.Equal(packed, expected) { 207 t.Errorf("pack record: %x expected: %x", packed, expected) 208 t.Errorf("*** GENERATED Packed:\n%s", util.FormatBytes("expected", packed)) 209 t.Fatal("fatal error") 210 } 211 212 t.Logf("Packed length: %d bytes", len(packed)) 213 214 // check txId 215 txId := packed.MakeLink() 216 217 if txId != expectedTxId { 218 t.Errorf("pack txId: %#v expected: %x", txId, expectedTxId) 219 t.Errorf("*** GENERATED txId:\n%s", util.FormatBytes("expectedTxId", txId[:])) 220 t.Fatal("fatal error") 221 } 222 223 // test the unpacker 224 unpacked, n, err := packed.Unpack(true) 225 if nil != err { 226 t.Fatalf("unpack error: %s", err) 227 } 228 if len(packed) != n { 229 t.Errorf("did not unpack all data: only used: %d of: %d bytes", n, len(packed)) 230 } 231 232 bmt, ok := unpacked.(*transactionrecord.BitmarkTransferCountersigned) 233 if !ok { 234 t.Fatalf("did not unpack to BitmarkTransferCountersigned") 235 } 236 237 // display a JSON version for information 238 item := struct { 239 TxId merkle.Digest 240 BitmarkTransferCountersigned *transactionrecord.BitmarkTransferCountersigned 241 }{ 242 txId, 243 bmt, 244 } 245 b, err := json.MarshalIndent(item, "", " ") 246 if nil != err { 247 t.Fatalf("json error: %s", err) 248 } 249 250 t.Logf("Bitmark Transfer: JSON: %s", b) 251 252 // check that structure is preserved through Pack/Unpack 253 // note reg is a pointer here 254 if !reflect.DeepEqual(r, *bmt) { 255 t.Fatalf("different, original: %v recovered: %v", r, *bmt) 256 } 257} 258 259// test the packing/unpacking of Bitmark transfer record 260// 261// test transfer to transfer 262// ensures that pack->unpack returns the same original value 263func TestPackBitmarkTransferCountersignedThree(t *testing.T) { 264 265 ownerOneAccount := makeAccount(ownerOne.publicKey) 266 ownerTwoAccount := makeAccount(ownerTwo.publicKey) 267 268 var link merkle.Digest 269 err := merkleDigestFromLE("14eb103a0c8fb22e50e73ae9b4ff88595b1cd5f60c4afb690d8fbd014c3ed091", &link) 270 if nil != err { 271 t.Fatalf("hex to link error: %s", err) 272 } 273 274 r := transactionrecord.BitmarkTransferCountersigned{ 275 Link: link, 276 Escrow: nil, 277 Owner: ownerOneAccount, 278 } 279 280 expected := []byte{ 281 0x05, 0x20, 0x14, 0xeb, 0x10, 0x3a, 0x0c, 0x8f, 282 0xb2, 0x2e, 0x50, 0xe7, 0x3a, 0xe9, 0xb4, 0xff, 283 0x88, 0x59, 0x5b, 0x1c, 0xd5, 0xf6, 0x0c, 0x4a, 284 0xfb, 0x69, 0x0d, 0x8f, 0xbd, 0x01, 0x4c, 0x3e, 285 0xd0, 0x91, 0x00, 0x21, 0x13, 0x27, 0x64, 0x0e, 286 0x4a, 0xab, 0x92, 0xd8, 0x7b, 0x4a, 0x6a, 0x2f, 287 0x30, 0xb8, 0x81, 0xf4, 0x49, 0x29, 0xf8, 0x66, 288 0x04, 0x3a, 0x84, 0x1c, 0x38, 0x14, 0xb1, 0x66, 289 0xb8, 0x89, 0x44, 0xb0, 0x92, 290 } 291 292 expectedTxId := merkle.Digest{ 293 0xb9, 0xdd, 0xe2, 0x87, 0x3a, 0x98, 0x21, 0xaa, 294 0x27, 0x52, 0x13, 0x76, 0x91, 0x4c, 0x8c, 0xb1, 295 0x17, 0x9d, 0xb6, 0x36, 0xd3, 0x72, 0xaa, 0x4a, 296 0x2a, 0x25, 0xfa, 0x2e, 0x15, 0x88, 0x3a, 0xb5, 297 } 298 299 // manually sign the record and attach signature to "expected" 300 signature := ed25519.Sign(ownerTwo.privateKey, expected) 301 r.Signature = signature 302 l := util.ToVarint64(uint64(len(signature))) 303 expected = append(expected, l...) 304 expected = append(expected, signature...) 305 306 // manually countersign the record and attach countersignature to "expected" 307 signature = ed25519.Sign(ownerOne.privateKey, expected) 308 r.Countersignature = signature 309 l = util.ToVarint64(uint64(len(signature))) 310 expected = append(expected, l...) 311 expected = append(expected, signature...) 312 313 // test the packer 314 packed, err := r.Pack(ownerTwoAccount) 315 if nil != err { 316 t.Errorf("pack error: %s", err) 317 } 318 319 // if either of above fail we will have the message _without_ a signature 320 if !bytes.Equal(packed, expected) { 321 t.Errorf("pack record: %x expected: %x", packed, expected) 322 t.Errorf("*** GENERATED Packed:\n%s", util.FormatBytes("expected", packed)) 323 t.Fatal("fatal error") 324 } 325 326 t.Logf("Packed length: %d bytes", len(packed)) 327 328 // check txId 329 txId := packed.MakeLink() 330 331 if txId != expectedTxId { 332 t.Errorf("pack txId: %#v expected: %x", txId, expectedTxId) 333 t.Errorf("*** GENERATED txId:\n%s", util.FormatBytes("expectedTxId", txId[:])) 334 t.Fatal("fatal error") 335 } 336 337 // test the unpacker 338 unpacked, n, err := packed.Unpack(true) 339 if nil != err { 340 t.Fatalf("unpack error: %s", err) 341 } 342 if len(packed) != n { 343 t.Errorf("did not unpack all data: only used: %d of: %d bytes", n, len(packed)) 344 } 345 346 bmt, ok := unpacked.(*transactionrecord.BitmarkTransferCountersigned) 347 if !ok { 348 t.Fatalf("did not unpack to BitmarkTransferCountersigned") 349 } 350 351 // display a JSON version for information 352 item := struct { 353 TxId merkle.Digest 354 BitmarkTransferCountersigned *transactionrecord.BitmarkTransferCountersigned 355 }{ 356 txId, 357 bmt, 358 } 359 b, err := json.MarshalIndent(item, "", " ") 360 if nil != err { 361 t.Fatalf("json error: %s", err) 362 } 363 364 t.Logf("Bitmark Transfer: JSON: %s", b) 365 366 // check that structure is preserved through Pack/Unpack 367 // note reg is a pointer here 368 if !reflect.DeepEqual(r, *bmt) { 369 t.Fatalf("different, original: %v recovered: %v", r, *bmt) 370 } 371} 372 373// test the packing/unpacking of Bitmark transfer record 374// 375// check for error on incorrect countersignature 376func TestPackBitmarkTransferCountersignedFail(t *testing.T) { 377 378 ownerOneAccount := makeAccount(ownerOne.publicKey) 379 ownerTwoAccount := makeAccount(ownerTwo.publicKey) 380 381 var link merkle.Digest 382 err := merkleDigestFromLE("14eb103a0c8fb22e50e73ae9b4ff88595b1cd5f60c4afb690d8fbd014c3ed091", &link) 383 if nil != err { 384 t.Fatalf("hex to link error: %s", err) 385 } 386 387 r := transactionrecord.BitmarkTransferCountersigned{ 388 Link: link, 389 Escrow: nil, 390 Owner: ownerOneAccount, 391 } 392 393 expected := []byte{ 394 0x05, 0x20, 0x14, 0xeb, 0x10, 0x3a, 0x0c, 0x8f, 395 0xb2, 0x2e, 0x50, 0xe7, 0x3a, 0xe9, 0xb4, 0xff, 396 0x88, 0x59, 0x5b, 0x1c, 0xd5, 0xf6, 0x0c, 0x4a, 397 0xfb, 0x69, 0x0d, 0x8f, 0xbd, 0x01, 0x4c, 0x3e, 398 0xd0, 0x91, 0x00, 0x21, 0x13, 0x27, 0x64, 0x0e, 399 0x4a, 0xab, 0x92, 0xd8, 0x7b, 0x4a, 0x6a, 0x2f, 400 0x30, 0xb8, 0x81, 0xf4, 0x49, 0x29, 0xf8, 0x66, 401 0x04, 0x3a, 0x84, 0x1c, 0x38, 0x14, 0xb1, 0x66, 402 0xb8, 0x89, 0x44, 0xb0, 0x92, 403 } 404 405 // manually sign the record and attach signature to "expected" 406 signature := ed25519.Sign(ownerTwo.privateKey, expected) 407 r.Signature = signature 408 l := util.ToVarint64(uint64(len(signature))) 409 expected = append(expected, l...) 410 expected = append(expected, signature...) 411 412 // manually countersign the record and attach countersignature to "expected" 413 signature = ed25519.Sign(ownerTwo.privateKey, expected) // wrong signature 414 r.Countersignature = signature 415 416 // test the packer 417 _, err = r.Pack(ownerTwoAccount) 418 if fault.InvalidSignature == err { 419 return 420 } 421 if nil == err { 422 t.Error("unexpected pack success, should fail with invalid signature") 423 } else { 424 t.Errorf("pack error: %s", err) 425 } 426 427 t.Fatal("fatal error") 428} 429 430// test the pack failure on trying to use the zero public key 431func TestPackBitmarkTransferCountersignedFromZeroAccount(t *testing.T) { 432 433 ownerDeletedAccount := makeAccount(theZeroKey.publicKey) 434 ownerOneAccount := makeAccount(ownerOne.publicKey) 435 436 var link merkle.Digest 437 err := merkleDigestFromLE("14eb103a0c8fb22e50e73ae9b4ff88595b1cd5f60c4afb690d8fbd014c3ed091", &link) 438 if nil != err { 439 t.Fatalf("hex to link error: %s", err) 440 } 441 442 r := transactionrecord.BitmarkTransferCountersigned{ 443 Link: link, 444 Escrow: nil, 445 Owner: ownerOneAccount, 446 Signature: []byte{1, 2, 3, 4}, 447 Countersignature: []byte{1, 2, 3, 4}, 448 } 449 450 // test the packer 451 _, err = r.Pack(ownerDeletedAccount) 452 if nil == err { 453 t.Fatalf("pack should have failed") 454 } 455 if fault.InvalidOwnerOrRegistrant != err { 456 t.Fatalf("unexpected pack error: %s", err) 457 } 458} 459 460// test the pack failure on trying to use the zero public key 461func TestPackBitmarkTransferCountersignedToZeroAccount(t *testing.T) { 462 463 ownerOneAccount := makeAccount(ownerOne.publicKey) 464 ownerDeletedAccount := makeAccount(theZeroKey.publicKey) 465 466 var link merkle.Digest 467 err := merkleDigestFromLE("14eb103a0c8fb22e50e73ae9b4ff88595b1cd5f60c4afb690d8fbd014c3ed091", &link) 468 if nil != err { 469 t.Fatalf("hex to link error: %s", err) 470 } 471 472 r := transactionrecord.BitmarkTransferCountersigned{ 473 Link: link, 474 Escrow: nil, 475 Owner: ownerDeletedAccount, 476 Signature: []byte{1, 2, 3, 4}, 477 Countersignature: []byte{1, 2, 3, 4}, 478 } 479 480 // test the packer 481 _, err = r.Pack(ownerOneAccount) 482 if nil == err { 483 t.Fatalf("pack should have failed") 484 } 485 if fault.InvalidOwnerOrRegistrant != err { 486 t.Fatalf("unexpected pack error: %s", err) 487 } 488} 489