11 "github.com/davecgh/go-spew/spew"
13 "github.com/bytom/errors"
14 "github.com/bytom/protocol/bc"
15 "github.com/bytom/testutil"
18 func TestTransactionTrailingGarbage(t *testing.T) {
19 const validTxHex = `0701000001012b00030a0908916133a0d64d1d973b631e226ef95338ad4a536b95635f32f0d04708a6f2a26380a094a58d1d09000101010103010203010129000000000000000000000000000000000000000000000000000000000000000080a094a58d1d01010100`
22 err := validTx.UnmarshalText([]byte(validTxHex))
27 invalidTxHex := validTxHex + strings.Repeat("beef", 10)
29 err = invalidTx.UnmarshalText([]byte(invalidTxHex))
31 t.Fatal("expected error with trailing garbage but got nil")
35 func TestTransaction(t *testing.T) {
36 issuanceScript := []byte{1}
38 assetID := bc.ComputeAssetID(issuanceScript, 1, &bc.EmptyStringHash)
48 SerializedSize: uint64(6),
52 hex: ("07" + // serflags
53 "01" + // transaction version
55 "00" + // common witness extensible string length
56 "00" + // inputs count
57 "00"), // outputs count
58 hash: mustDecodeHash("b28048bd60c4c13144fd34f408627d1be68f6cb4fdd34e879d6d791060ea7d60"),
63 SerializedSize: uint64(105),
65 NewIssuanceInput([]byte{10, 9, 8}, 1000000000000, issuanceScript, [][]byte{[]byte{1, 2, 3}}, nil),
68 NewTxOutput(bc.AssetID{}, 1000000000000, []byte{1}),
71 hex: ("0701000001012b00030a0908916133a0d64d1d973b631e226ef95338ad4a536b95635f32f0d04708a6f2a26380a094a58d1d09000101010103010203010129000000000000000000000000000000000000000000000000000000000000000080a094a58d1d01010100"), // reference data
72 hash: mustDecodeHash("7e6928130bc91e115f6ebe1fb4238d51e4155a7f9f809a36a5ebea7342ad1f63"),
77 SerializedSize: uint64(174),
79 NewSpendInput(nil, mustDecodeHash("dd385f6fe25d91d8c1bd0fa58951ad56b0c5229dcc01f61d9f9e8b9eb92d3292"), bc.AssetID{}, 1000000000000, 1, []byte{1}),
82 NewTxOutput(assetID, 600000000000, []byte{1}),
83 NewTxOutput(assetID, 400000000000, []byte{2}),
86 hex: ("0701000001014c014add385f6fe25d91d8c1bd0fa58951ad56b0c5229dcc01f61d9f9e8b9eb92d3292000000000000000000000000000000000000000000000000000000000000000080a094a58d1d010101010100020129916133a0d64d1d973b631e226ef95338ad4a536b95635f32f0d04708a6f2a26380e0a596bb11010101000129916133a0d64d1d973b631e226ef95338ad4a536b95635f32f0d04708a6f2a26380c0ee8ed20b01010200"), // output 1, output witness
87 hash: mustDecodeHash("e89ea19ec8acb92d697c06ebf841020bb9f1d9ace983efcb47c09913cff99026"),
90 for i, test := range cases {
91 got := serialize(t, test.tx)
92 want, _ := hex.DecodeString(test.hex)
93 if !bytes.Equal(got, want) {
94 t.Errorf("test %d: bytes = %x want %x", i, got, want)
96 if test.tx.ID != test.hash {
97 t.Errorf("test %d: hash = %x want %x", i, test.tx.ID.Bytes(), test.hash.Bytes())
100 txJSON, err := json.Marshal(test.tx)
102 t.Errorf("test %d: error marshaling tx to json: %s", i, err)
105 if err := json.Unmarshal(txJSON, &txFromJSON); err != nil {
106 t.Errorf("test %d: error unmarshaling tx from json: %s", i, err)
108 if !testutil.DeepEqual(test.tx.TxData, txFromJSON.TxData) {
109 t.Errorf("test %d: types.TxData -> json -> types.TxData: got:\n%s\nwant:\n%s", i, spew.Sdump(txFromJSON.TxData), spew.Sdump(test.tx.TxData))
113 if err := tx1.UnmarshalText([]byte(test.hex)); err != nil {
114 t.Errorf("test %d: unexpected err %v", i, err)
116 if !testutil.DeepEqual(*tx1, test.tx.TxData) {
117 t.Errorf("test %d: tx1 is:\n%swant:\n%s", i, spew.Sdump(*tx1), spew.Sdump(test.tx.TxData))
122 func TestHasIssuance(t *testing.T) {
128 Inputs: []*TxInput{NewIssuanceInput(nil, 0, nil, nil, nil)},
134 NewSpendInput(nil, bc.Hash{}, bc.AssetID{}, 0, 0, nil),
135 NewIssuanceInput(nil, 0, nil, nil, nil),
142 NewSpendInput(nil, bc.Hash{}, bc.AssetID{}, 0, 0, nil),
151 for _, c := range cases {
152 got := c.tx.HasIssuance()
154 t.Errorf("HasIssuance(%+v) = %v want %v", c.tx, got, c.want)
159 func TestInvalidIssuance(t *testing.T) {
160 hex := ("07" + // serflags
161 "01" + // transaction version
163 "00" + // common witness extensible string length
164 "01" + // inputs count
165 "01" + // input 0, asset version
166 "2b" + // input 0, input commitment length prefix
167 "00" + // input 0, input commitment, "issuance" type
168 "03" + // input 0, input commitment, nonce length prefix
169 "0a0908" + // input 0, input commitment, nonce
170 "0000000000000000000000000000000000000000000000000000000000000000" + // input 0, input commitment, WRONG asset id
171 "80a094a58d1d" + // input 0, input commitment, amount
172 "29" + // input 0, issuance input witness length prefix
173 "03deff1d4319d67baa10a6d26c1fea9c3e8d30e33474efee1a610a9bb49d758d" + // input 0, issuance input witness, initial block
174 "00" + // input 0, issuance input witness, asset definition
175 "01" + // input 0, issuance input witness, vm version
176 "01" + // input 0, issuance input witness, issuance program length prefix
177 "01" + // input 0, issuance input witness, issuance program
178 "01" + // input 0, issuance input witness, arguments count
179 "03" + // input 0, issuance input witness, argument 0 length prefix
180 "010203" + // input 0, issuance input witness, argument 0
181 "01" + // outputs count
182 "01" + // output 0, asset version
183 "29" + // output 0, output commitment length
184 "0000000000000000000000000000000000000000000000000000000000000000" + // output 0, output commitment, asset id
185 "80a094a58d1d" + // output 0, output commitment, amount
186 "01" + // output 0, output commitment, vm version
187 "0101" + // output 0, output commitment, control program
188 "066f7574707574" + // output 0, reference data
189 "00" + // output 0, output witness
190 "0869737375616e6365")
192 err := tx.UnmarshalText([]byte(hex))
193 if errors.Root(err) != errBadAssetID {
194 t.Errorf("want errBadAssetID, got %v", err)
198 func BenchmarkTxWriteToTrue(b *testing.B) {
200 for i := 0; i < b.N; i++ {
201 tx.writeTo(ioutil.Discard, 0)
205 func BenchmarkTxWriteToFalse(b *testing.B) {
207 for i := 0; i < b.N; i++ {
208 tx.writeTo(ioutil.Discard, serRequired)
212 func BenchmarkTxWriteToTrue200(b *testing.B) {
214 for i := 0; i < 200; i++ {
215 tx.Inputs = append(tx.Inputs, NewSpendInput(nil, bc.Hash{}, bc.AssetID{}, 0, 0, nil))
216 tx.Outputs = append(tx.Outputs, NewTxOutput(bc.AssetID{}, 0, nil))
218 for i := 0; i < b.N; i++ {
219 tx.writeTo(ioutil.Discard, 0)
223 func BenchmarkTxWriteToFalse200(b *testing.B) {
225 for i := 0; i < 200; i++ {
226 tx.Inputs = append(tx.Inputs, NewSpendInput(nil, bc.Hash{}, bc.AssetID{}, 0, 0, nil))
227 tx.Outputs = append(tx.Outputs, NewTxOutput(bc.AssetID{}, 0, nil))
229 for i := 0; i < b.N; i++ {
230 tx.writeTo(ioutil.Discard, serRequired)
234 func BenchmarkTxInputWriteToTrue(b *testing.B) {
235 input := NewSpendInput(nil, bc.Hash{}, bc.AssetID{}, 0, 0, nil)
236 ew := errors.NewWriter(ioutil.Discard)
237 for i := 0; i < b.N; i++ {
242 func BenchmarkTxInputWriteToFalse(b *testing.B) {
243 input := NewSpendInput(nil, bc.Hash{}, bc.AssetID{}, 0, 0, nil)
244 ew := errors.NewWriter(ioutil.Discard)
245 for i := 0; i < b.N; i++ {
246 input.writeTo(ew, serRequired)
250 func BenchmarkTxOutputWriteToTrue(b *testing.B) {
251 output := NewTxOutput(bc.AssetID{}, 0, nil)
252 ew := errors.NewWriter(ioutil.Discard)
253 for i := 0; i < b.N; i++ {
254 output.writeTo(ew, 0)
258 func BenchmarkTxOutputWriteToFalse(b *testing.B) {
259 output := NewTxOutput(bc.AssetID{}, 0, nil)
260 ew := errors.NewWriter(ioutil.Discard)
261 for i := 0; i < b.N; i++ {
262 output.writeTo(ew, serRequired)
266 func BenchmarkAssetAmountWriteTo(b *testing.B) {
267 aa := bc.AssetAmount{}
268 for i := 0; i < b.N; i++ {
269 aa.WriteTo(ioutil.Discard)