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 "encoding/json" 10 "fmt" 11 "testing" 12 13 "github.com/bitmark-inc/bitmarkd/fault" 14 "github.com/bitmark-inc/bitmarkd/transactionrecord" 15 "github.com/bitmark-inc/bitmarkd/util" 16) 17 18// test invalid asset identifiers 19func TestInvalidAssetIdentifiers(t *testing.T) { 20 21 invalid := []string{ 22 "", 23 "4b", // one byte 24 "4bf", // odd number of chars 25 "4473fb34cc05ed9599935a0098", // truncated 26 "4473fb34cc05ed9599935a0098ce060dfa546f40932dd7b40d35f8fe5cd6a4ff26f3dbf8ffc86ee8eb6480facfd83f3e20d69bf1e764a59256cf79b89531de3", // just one short 27 "4473fb34cc05ed9599935a0098ce060dfa546f40932dd7b40d35f8fe5cd6a4ff26f3dbf8ffc86ee8eb6480facfd83f3e20d69bf1e764a59256cf79b89531de379", // just one char over 28 "4473fb34cc05ed9599935a0098ce060dfa546f40932dd7b40d35f8fe5cd6a4ff26f3dbf8ffc86ee8eb6480facfd83f3e20d69bf1e764a59256cf79b89531de3745", // just one byte over 29 30 "BAM04473fb34cc05ed9599935a0098ce060dfa546f40932dd7b40d35f8fe5cd6a4ff26f3dbf8ffc86ee8eb6480facfd83f3e20d69bf1e764a59256cf79b89531de37", // bad prefix 31 "ABM04473fb34cc05ed9599935a0098ce060dfa546f40932dd7b40d35f8fe5cd6a4ff26f3dbf8ffc86ee8eb6480facfd83f3e20d69bf1e764a59256cf79b89531de37", // bad prefix 32 "QWRT4473fb34cc05ed9599935a0098ce060dfa546f40932dd7b40d35f8fe5cd6a4ff26f3dbf8ffc86ee8eb6480facfd83f3e20d69bf1e764a59256cf79b89531de37", // bad prefix 33 34 "4473fb34cc05ed9599x35a0098ce060dfa546f40932dd7b40d35f8fe5cd6a4ff26f3dbf8ffc86ee8eb6480facfd83f3e20d69bf1e764a59256cf79b89531de37", // invalid hex char x 35 "4473fb34cc05ed9599X35a0098ce060dfa546f40932dd7b40d35f8fe5cd6a4ff26f3dbf8ffc86ee8eb6480facfd83f3e20d69bf1e764a59256cf79b89531de37", // invalid hex char X 36 "4473fb34cc05ed9599k35a0098ce060dfa546f40932dd7b40d35f8fe5cd6a4ff26f3dbf8ffc86ee8eb6480facfd83f3e20d69bf1e764a59256cf79b89531de37", // invalid hex char k 37 "4473fb34cc05ed9599K35a0098ce060dfa546f40932dd7b40d35f8fe5cd6a4ff26f3dbf8ffc86ee8eb6480facfd83f3e20d69bf1e764a59256cf79b89531de37", // invalid hex char K 38 } 39 40 for i, textAssetIdentifier := range invalid { 41 var link transactionrecord.AssetIdentifier 42 n, err := fmt.Sscan(textAssetIdentifier, &link) 43 if fault.NotAssetId != err { 44 t.Errorf("%d: testing: %q", i, textAssetIdentifier) 45 t.Errorf("%d: expected fault.NotAssetIdentifier but got: %v", i, err) 46 return 47 } 48 if 0 != n { 49 t.Errorf("%d: testing: %q", i, textAssetIdentifier) 50 t.Errorf("%d: hex to link scanned: %d expected: 0", i, n) 51 return 52 } 53 } 54} 55 56// test asset id conversion 57func TestAssetIdentifier(t *testing.T) { 58 59 expectedAssetIdentifier := transactionrecord.AssetIdentifier{ 60 0x37, 0xde, 0x31, 0x95, 0xb8, 0x79, 0xcf, 0x56, 61 0x92, 0xa5, 0x64, 0xe7, 0xf1, 0x9b, 0xd6, 0x20, 62 0x3e, 0x3f, 0xd8, 0xcf, 0xfa, 0x80, 0x64, 0xeb, 63 0xe8, 0x6e, 0xc8, 0xff, 0xf8, 0xdb, 0xf3, 0x26, 64 0xff, 0xa4, 0xd6, 0x5c, 0xfe, 0xf8, 0x35, 0x0d, 65 0xb4, 0xd7, 0x2d, 0x93, 0x40, 0x6f, 0x54, 0xfa, 66 0x0d, 0x06, 0xce, 0x98, 0x00, 0x5a, 0x93, 0x99, 67 0x95, 0xed, 0x05, 0xcc, 0x34, 0xfb, 0x73, 0x44, 68 } 69 70 textAssetIdentifier := "37de3195b879cf5692a564e7f19bd6203e3fd8cffa8064ebe86ec8fff8dbf326ffa4d65cfef8350db4d72d93406f54fa0d06ce98005a939995ed05cc34fb7344" 71 72 if expectedAssetIdentifier.String() != textAssetIdentifier { 73 t.Errorf("asset id(%%s): %s expected: %s", expectedAssetIdentifier, textAssetIdentifier) 74 } 75 76 if fmt.Sprintf("%v", expectedAssetIdentifier) != textAssetIdentifier { 77 t.Errorf("asset id(%%v): %v expected: %s", expectedAssetIdentifier, textAssetIdentifier) 78 } 79 80 if fmt.Sprintf("%#v", expectedAssetIdentifier) != "<asset:"+textAssetIdentifier+">" { 81 t.Errorf("asset id(%%#v): %#v expected: %s", expectedAssetIdentifier, "<asset:"+textAssetIdentifier+">") 82 } 83 84 var asset transactionrecord.AssetIdentifier 85 n, err := fmt.Sscan("37de3195b879cf5692a564e7f19bd6203e3fd8cffa8064ebe86ec8fff8dbf326ffa4d65cfef8350db4d72d93406f54fa0d06ce98005a939995ed05cc34fb7344", &asset) 86 if nil != err { 87 t.Fatalf("hex to link error: %s", err) 88 } 89 if 1 != n { 90 t.Fatalf("hex to link scanned: %d expected: 1", n) 91 } 92 93 if asset != expectedAssetIdentifier { 94 t.Errorf("asset: %#v expected: %#v", asset, expectedAssetIdentifier) 95 t.Errorf("*** GENERATED asset:\n%s", util.FormatBytes("expectedAssetIdentifier", asset[:])) 96 } 97 98 // check JSON conversion 99 expectedJSON := `{"AssetIdentifier":"37de3195b879cf5692a564e7f19bd6203e3fd8cffa8064ebe86ec8fff8dbf326ffa4d65cfef8350db4d72d93406f54fa0d06ce98005a939995ed05cc34fb7344"}` 100 101 item := struct { 102 AssetIdentifier transactionrecord.AssetIdentifier 103 }{ 104 asset, 105 } 106 convertedJSON, err := json.Marshal(item) 107 if nil != err { 108 t.Fatalf("marshal json error: %s", err) 109 } 110 if expectedJSON != string(convertedJSON) { 111 t.Errorf("JSON converted: %q", convertedJSON) 112 t.Errorf(" expected: %q", expectedJSON) 113 } 114 115 // test json unmarshal 116 var newItem struct { 117 AssetIdentifier transactionrecord.AssetIdentifier 118 } 119 err = json.Unmarshal([]byte(expectedJSON), &newItem) 120 if nil != err { 121 t.Fatalf("unmarshal json error: %s", err) 122 } 123 124 if newItem.AssetIdentifier != expectedAssetIdentifier { 125 t.Errorf("link: %#v expected: %#v", newItem.AssetIdentifier, expectedAssetIdentifier) 126 } 127 128} 129 130// test asset id bytes 131func TestAssetIdentifierFromBytes(t *testing.T) { 132 133 expectedAssetId := transactionrecord.AssetIdentifier{ 134 0x37, 0xde, 0x31, 0x95, 0xb8, 0x79, 0xcf, 0x56, 135 0x92, 0xa5, 0x64, 0xe7, 0xf1, 0x9b, 0xd6, 0x20, 136 0x3e, 0x3f, 0xd8, 0xcf, 0xfa, 0x80, 0x64, 0xeb, 137 0xe8, 0x6e, 0xc8, 0xff, 0xf8, 0xdb, 0xf3, 0x26, 138 0xff, 0xa4, 0xd6, 0x5c, 0xfe, 0xf8, 0x35, 0x0d, 139 0xb4, 0xd7, 0x2d, 0x93, 0x40, 0x6f, 0x54, 0xfa, 140 0x0d, 0x06, 0xce, 0x98, 0x00, 0x5a, 0x93, 0x99, 141 0x95, 0xed, 0x05, 0xcc, 0x34, 0xfb, 0x73, 0x44, 142 } 143 144 valid := []byte{ 145 0x37, 0xde, 0x31, 0x95, 0xb8, 0x79, 0xcf, 0x56, 146 0x92, 0xa5, 0x64, 0xe7, 0xf1, 0x9b, 0xd6, 0x20, 147 0x3e, 0x3f, 0xd8, 0xcf, 0xfa, 0x80, 0x64, 0xeb, 148 0xe8, 0x6e, 0xc8, 0xff, 0xf8, 0xdb, 0xf3, 0x26, 149 0xff, 0xa4, 0xd6, 0x5c, 0xfe, 0xf8, 0x35, 0x0d, 150 0xb4, 0xd7, 0x2d, 0x93, 0x40, 0x6f, 0x54, 0xfa, 151 0x0d, 0x06, 0xce, 0x98, 0x00, 0x5a, 0x93, 0x99, 152 0x95, 0xed, 0x05, 0xcc, 0x34, 0xfb, 0x73, 0x44, 153 } 154 155 var assetId transactionrecord.AssetIdentifier 156 err := transactionrecord.AssetIdentifierFromBytes(&assetId, valid) 157 if nil != err { 158 t.Fatalf("AssetIdentifierFromBytes error: %s", err) 159 } 160 161 if assetId != expectedAssetId { 162 t.Fatalf("assetIdentifier expected: %v actual: %v", expectedAssetId, assetId) 163 } 164 165 err = transactionrecord.AssetIdentifierFromBytes(&assetId, valid[1:]) 166 if fault.NotAssetId != err { 167 t.Fatalf("AssetIdentifierFromBytes error: %s", err) 168 } 169} 170