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/fault" 17 "github.com/bitmark-inc/bitmarkd/merkle" 18 "github.com/bitmark-inc/bitmarkd/transactionrecord" 19 "github.com/bitmark-inc/bitmarkd/util" 20) 21 22// test the packing/unpacking of Share grant record 23// 24// ensures that pack->unpack returns the same original value 25func TestPackShareGrant(t *testing.T) { 26 27 ownerOneAccount := makeAccount(ownerOne.publicKey) 28 ownerTwoAccount := makeAccount(ownerTwo.publicKey) 29 30 var shareId merkle.Digest 31 err := merkleDigestFromLE("630c041cd1f586bcb9097e816189185c1e0379f67bbfc2f0626724f542047873", &shareId) 32 if nil != err { 33 t.Fatalf("hex to share error: %s", err) 34 } 35 36 r := transactionrecord.ShareGrant{ 37 ShareId: shareId, 38 Quantity: 100, 39 Owner: ownerOneAccount, 40 Recipient: ownerTwoAccount, 41 } 42 43 expected := []byte{ 44 0x09, 0x20, 0x63, 0x0c, 0x04, 0x1c, 0xd1, 0xf5, 45 0x86, 0xbc, 0xb9, 0x09, 0x7e, 0x81, 0x61, 0x89, 46 0x18, 0x5c, 0x1e, 0x03, 0x79, 0xf6, 0x7b, 0xbf, 47 0xc2, 0xf0, 0x62, 0x67, 0x24, 0xf5, 0x42, 0x04, 48 0x78, 0x73, 0x64, 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, 0x21, 0x13, 0xa1, 53 0x36, 0x32, 0xd5, 0x42, 0x5a, 0xed, 0x3a, 0x6b, 54 0x62, 0xe2, 0xbb, 0x6d, 0xe4, 0xc9, 0x59, 0x48, 55 0x41, 0xc1, 0x5b, 0x70, 0x15, 0x69, 0xec, 0x99, 56 0x99, 0xdc, 0x20, 0x1c, 0x35, 0xf7, 0xb3, 0x00, 57 } 58 59 expectedTxId := merkle.Digest{ 60 0x26, 0x65, 0xce, 0x93, 0x0e, 0x8b, 0x0d, 0xe6, 61 0x60, 0x58, 0x0d, 0xfa, 0xff, 0x05, 0x00, 0xb0, 62 0x9d, 0xf9, 0xfc, 0xe8, 0x90, 0x93, 0x1b, 0xca, 63 0x3b, 0x10, 0x1d, 0x3f, 0xb6, 0xf8, 0xa6, 0x1e, 64 } 65 66 // manually sign the record and attach signature to "expected" 67 signature := ed25519.Sign(ownerOne.privateKey, expected) 68 r.Signature = signature 69 l := util.ToVarint64(uint64(len(signature))) 70 expected = append(expected, l...) 71 expected = append(expected, signature...) 72 73 // manually countersign the record and attach countersignature to "expected" 74 signature = ed25519.Sign(ownerTwo.privateKey, expected) 75 r.Countersignature = signature 76 l = util.ToVarint64(uint64(len(signature))) 77 expected = append(expected, l...) 78 expected = append(expected, signature...) 79 80 // test the packer 81 packed, err := r.Pack(ownerOneAccount) 82 if nil != err { 83 t.Errorf("pack error: %s", err) 84 } 85 86 // if either of above fail we will have the message _without_ a signature 87 if !bytes.Equal(packed, expected) { 88 t.Errorf("pack record: %x expected: %x", packed, expected) 89 t.Errorf("*** GENERATED Packed:\n%s", util.FormatBytes("expected", packed)) 90 t.Fatal("fatal error") 91 } 92 93 t.Logf("Packed length: %d bytes", len(packed)) 94 95 // check txId 96 txId := packed.MakeLink() 97 98 if txId != expectedTxId { 99 t.Errorf("pack txId: %#v expected: %x", txId, expectedTxId) 100 t.Errorf("*** GENERATED txId:\n%s", util.FormatBytes("expectedTxId", txId[:])) 101 t.Fatal("fatal error") 102 } 103 104 // test the unpacker 105 unpacked, n, err := packed.Unpack(true) 106 if nil != err { 107 t.Fatalf("unpack error: %s", err) 108 } 109 if len(packed) != n { 110 t.Errorf("did not unpack all data: only used: %d of: %d bytes", n, len(packed)) 111 } 112 113 grant, ok := unpacked.(*transactionrecord.ShareGrant) 114 if !ok { 115 t.Fatalf("did not unpack to ShareGrant") 116 } 117 118 // display a JSON version for information 119 item := struct { 120 TxId merkle.Digest 121 ShareGrant *transactionrecord.ShareGrant 122 }{ 123 txId, 124 grant, 125 } 126 b, err := json.MarshalIndent(item, "", " ") 127 if nil != err { 128 t.Fatalf("json error: %s", err) 129 } 130 131 t.Logf("Share Grant: JSON: %s", b) 132 133 // check that structure is preserved through Pack/Unpack 134 // note reg is a pointer here 135 if !reflect.DeepEqual(r, *grant) { 136 t.Fatalf("different, original: %v recovered: %v", r, *grant) 137 } 138} 139 140// test the packing/unpacking of Share grant record 141// 142// ensures that value cannot be zero 143func TestPackShareGrantValueNotZero(t *testing.T) { 144 145 ownerOneAccount := makeAccount(ownerOne.publicKey) 146 ownerTwoAccount := makeAccount(ownerTwo.publicKey) 147 148 var shareId merkle.Digest 149 err := merkleDigestFromLE("630c041cd1f586bcb9097e816189185c1e0379f67bbfc2f0626724f542047873", &shareId) 150 if nil != err { 151 t.Fatalf("hex to share error: %s", err) 152 } 153 154 r := transactionrecord.ShareGrant{ 155 ShareId: shareId, 156 Quantity: 0, 157 Owner: ownerOneAccount, 158 Recipient: ownerTwoAccount, 159 } 160 161 expected := []byte{ 162 0x09, 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, 0x00, 0x21, 0x13, 0x27, 0x64, 0x0e, 167 0x4a, 0xab, 0x92, 0xd8, 0x7b, 0x4a, 0x6a, 0x2f, 168 0x30, 0xb8, 0x81, 0xf4, 0x49, 0x29, 0xf8, 0x66, 169 0x04, 0x3a, 0x84, 0x1c, 0x38, 0x14, 0xb1, 0x66, 170 0xb8, 0x89, 0x44, 0xb0, 0x92, 0x21, 0x13, 0xa1, 171 0x36, 0x32, 0xd5, 0x42, 0x5a, 0xed, 0x3a, 0x6b, 172 0x62, 0xe2, 0xbb, 0x6d, 0xe4, 0xc9, 0x59, 0x48, 173 0x41, 0xc1, 0x5b, 0x70, 0x15, 0x69, 0xec, 0x99, 174 0x99, 0xdc, 0x20, 0x1c, 0x35, 0xf7, 0xb3, 0x00, 175 } 176 177 // manually sign the record and attach signature to "expected" 178 signature := ed25519.Sign(ownerOne.privateKey, expected) 179 r.Signature = signature 180 l := util.ToVarint64(uint64(len(signature))) 181 expected = append(expected, l...) 182 expected = append(expected, signature...) 183 184 // manually countersign the record and attach countersignature to "expected" 185 signature = ed25519.Sign(ownerTwo.privateKey, expected) 186 r.Countersignature = signature 187 188 // test the packer 189 _, err = r.Pack(ownerOneAccount) 190 if fault.ShareQuantityTooSmall != err { 191 t.Fatalf("unexpected pack error: %s", err) 192 } 193} 194