8 "github.com/vapor/account"
9 "github.com/vapor/blockchain/signers"
10 "github.com/vapor/consensus"
11 "github.com/vapor/crypto/ed25519/chainkd"
12 "github.com/vapor/protocol/bc"
13 "github.com/vapor/protocol/bc/types"
14 "github.com/vapor/protocol/validation"
15 "github.com/vapor/protocol/vm/vmutil"
16 "github.com/vapor/testutil"
19 func TestValidateUglyTx(t *testing.T) {
20 singleSignInst := &signingInst{
21 rootPrvKeys: []string{
22 "38d2c44314c401b3ea7c23c54e12c36a527aee46a7f26b82443a46bf40583e439dea25de09b0018b35a741d8cd9f6ec06bc11db49762617485f5309ab72a12d4",
29 multiSignInst := &signingInst{
30 rootPrvKeys: []string{
31 "a080aca2d9d7948d005c92d0729c618e56fb5551a52dfa04dc4caaf3c8b8a94c89a9795f5bbfd2b885ce7a9d3e3efa5386436c3681b21f9263a0b0a544346b48",
32 "105295324626e33bb7d8e8a57c6a0aa495346d7fc342a4891ece00424494cf48f75cefa0f8c61674a12238cfa711b4bc26cb22f38b6e2206c691b83943a58312",
33 "c02bb73d1aee56f8935fb7704f71f668eb37ec223baf5723b38a186669b465427d1bdbc2c4397c1259d12b6229aaf6154aaccdeb8addce3a780a1cbc1025ad25",
34 "a0c2225685e4c4439f12c264d1573db063ddbc929d4b8a3e1641e8abb4df504a56b1200b9925138d79febe6e1156fcfaf0d1878f25cbccc5db4c8fea55bde198",
35 "20d06d4fd261ab554e01104f019392f89566acace727e6bb6de4544aa3a6b248480232155332e6e5de10a62e4a9a4c1d9e3b7f9cb4fd196142ef1d080b8bbaec",
51 category: "fee insufficient",
52 desc: "sum of btm output greater than btm input",
53 insts: []*signingInst{singleSignInst},
56 Inputs: []*types.TxInput{
57 types.NewSpendInput(nil,
58 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
59 *consensus.BTMAssetID, 10000000000, 0, nil),
61 Outputs: []*types.TxOutput{
62 types.NewIntraChainOutput(*consensus.BTMAssetID, 10000000001, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
69 category: "fee insufficient",
70 desc: "sum of btm output equals to input btm",
71 insts: []*signingInst{singleSignInst},
74 Inputs: []*types.TxInput{
75 types.NewSpendInput(nil,
76 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
77 *consensus.BTMAssetID, 10000000000, 0, nil),
79 Outputs: []*types.TxOutput{
80 types.NewIntraChainOutput(*consensus.BTMAssetID, 10000000001, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
87 category: "fee insufficient",
88 desc: "sum of btm input greater than btm output, but still insufficient",
89 insts: []*signingInst{singleSignInst},
92 Inputs: []*types.TxInput{
93 types.NewSpendInput(nil,
94 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
95 *consensus.BTMAssetID, 10000000001, 0, nil),
97 Outputs: []*types.TxOutput{
98 types.NewIntraChainOutput(*consensus.BTMAssetID, 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
105 category: "fee insufficient",
106 desc: "no btm input",
107 insts: []*signingInst{singleSignInst},
108 txData: types.TxData{
110 Inputs: []*types.TxInput{
111 types.NewSpendInput(nil,
112 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
113 testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 0, nil),
115 Outputs: []*types.TxOutput{
116 types.NewIntraChainOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
123 category: "input output unbalance",
124 desc: "only has btm input, no output",
125 insts: []*signingInst{singleSignInst},
126 txData: types.TxData{
128 Inputs: []*types.TxInput{
129 types.NewSpendInput(nil,
130 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
131 *consensus.BTMAssetID, 10000000001, 0, nil),
133 Outputs: []*types.TxOutput{},
139 category: "input output unbalance",
140 desc: "issuance asset, no corresponding output",
141 insts: []*signingInst{singleSignInst, singleSignInst},
142 txData: types.TxData{
144 Inputs: []*types.TxInput{
145 types.NewSpendInput(nil,
146 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
147 *consensus.BTMAssetID, 10000000000, 0, nil),
148 types.NewIssuanceInput( // assetID: 97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f
149 testutil.MustDecodeHexString("fd0aec4229deb281"),
153 testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"),
156 Outputs: []*types.TxOutput{
157 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
164 category: "input output unbalance",
165 desc: "issuance asset A, output asset B",
166 insts: []*signingInst{singleSignInst, singleSignInst},
167 txData: types.TxData{
169 Inputs: []*types.TxInput{
170 types.NewSpendInput(nil,
171 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
172 *consensus.BTMAssetID, 10000000000, 0, nil),
173 types.NewIssuanceInput( // assetID: 97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f
174 testutil.MustDecodeHexString("fd0aec4229deb281"),
178 testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"),
181 Outputs: []*types.TxOutput{
182 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
183 types.NewIntraChainOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707e"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
190 category: "input output unbalance",
191 desc: "sum of output asset A greater than issuance asset A",
192 insts: []*signingInst{singleSignInst, singleSignInst},
193 txData: types.TxData{
195 Inputs: []*types.TxInput{
196 types.NewSpendInput(nil,
197 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
198 *consensus.BTMAssetID, 10000000000, 0, nil),
199 types.NewIssuanceInput( // assetID: 97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f
200 testutil.MustDecodeHexString("fd0aec4229deb281"),
204 testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"),
207 Outputs: []*types.TxOutput{
208 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
209 types.NewIntraChainOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 20000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
216 category: "input output unbalance",
217 desc: "sum of output asset A less than issuance asset A",
218 insts: []*signingInst{singleSignInst, singleSignInst},
219 txData: types.TxData{
221 Inputs: []*types.TxInput{
222 types.NewSpendInput(nil,
223 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
224 *consensus.BTMAssetID, 10000000000, 0, nil),
225 types.NewIssuanceInput( // assetID: 97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f
226 testutil.MustDecodeHexString("fd0aec4229deb281"),
230 testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"),
233 Outputs: []*types.TxOutput{
234 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
235 types.NewIntraChainOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 5000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
242 category: "input output unbalance",
243 desc: "sum of retire asset A greater than issuance asset A",
244 insts: []*signingInst{singleSignInst, singleSignInst},
245 txData: types.TxData{
247 Inputs: []*types.TxInput{
248 types.NewSpendInput(nil,
249 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
250 *consensus.BTMAssetID, 10000000000, 0, nil),
251 types.NewIssuanceInput( // assetID: 97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f
252 testutil.MustDecodeHexString("fd0aec4229deb281"),
256 testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"),
259 Outputs: []*types.TxOutput{
260 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
261 types.NewIntraChainOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 20000000000, testutil.MustDecodeHexString("6a")),
268 category: "input output unbalance",
269 desc: "sum of retire asset A less than issuance asset A",
270 insts: []*signingInst{singleSignInst, singleSignInst},
271 txData: types.TxData{
273 Inputs: []*types.TxInput{
274 types.NewSpendInput(nil,
275 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
276 *consensus.BTMAssetID, 10000000000, 0, nil),
277 types.NewIssuanceInput( // assetID: 97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f
278 testutil.MustDecodeHexString("fd0aec4229deb281"),
282 testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"),
285 Outputs: []*types.TxOutput{
286 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
287 types.NewIntraChainOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 5000000000, testutil.MustDecodeHexString("6a")),
294 category: "input output unbalance",
295 desc: "spend asset A, no corresponding output",
296 insts: []*signingInst{singleSignInst, singleSignInst},
297 txData: types.TxData{
299 Inputs: []*types.TxInput{
300 types.NewSpendInput(nil,
301 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
302 *consensus.BTMAssetID, 10000000000, 0, nil),
303 types.NewSpendInput(nil,
304 bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
305 testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 1, nil),
307 Outputs: []*types.TxOutput{
308 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
315 category: "input output unbalance",
316 desc: "spend asset A, output asset B",
317 insts: []*signingInst{singleSignInst, singleSignInst},
318 txData: types.TxData{
320 Inputs: []*types.TxInput{
321 types.NewSpendInput(nil,
322 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
323 *consensus.BTMAssetID, 10000000000, 0, nil),
324 types.NewSpendInput(nil,
325 bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
326 testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 1, nil),
328 Outputs: []*types.TxOutput{
329 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
330 types.NewIntraChainOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707e"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
337 category: "input output unbalance",
338 desc: "sum of output asset A greater than spend asset A",
339 insts: []*signingInst{singleSignInst, singleSignInst},
340 txData: types.TxData{
342 Inputs: []*types.TxInput{
343 types.NewSpendInput(nil,
344 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
345 *consensus.BTMAssetID, 10000000000, 0, nil),
346 types.NewSpendInput(nil,
347 bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
348 testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 1, nil),
350 Outputs: []*types.TxOutput{
351 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
352 types.NewIntraChainOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 20000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
359 category: "input output unbalance",
360 desc: "sum of output asset A less than spend asset A",
361 insts: []*signingInst{singleSignInst, singleSignInst},
362 txData: types.TxData{
364 Inputs: []*types.TxInput{
365 types.NewSpendInput(nil,
366 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
367 *consensus.BTMAssetID, 10000000000, 0, nil),
368 types.NewSpendInput(nil,
369 bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
370 testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 1, nil),
372 Outputs: []*types.TxOutput{
373 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
374 types.NewIntraChainOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 5000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
381 category: "input output unbalance",
382 desc: "sum of retire asset A greater than spend asset A",
383 insts: []*signingInst{singleSignInst, singleSignInst},
384 txData: types.TxData{
386 Inputs: []*types.TxInput{
387 types.NewSpendInput(nil,
388 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
389 *consensus.BTMAssetID, 10000000000, 0, nil),
390 types.NewSpendInput(nil,
391 bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
392 testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 1, nil),
394 Outputs: []*types.TxOutput{
395 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
396 types.NewIntraChainOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 20000000000, testutil.MustDecodeHexString("6a")),
403 category: "input output unbalance",
404 desc: "sum of retire asset A less than spend asset A",
405 insts: []*signingInst{singleSignInst, singleSignInst},
406 txData: types.TxData{
408 Inputs: []*types.TxInput{
409 types.NewSpendInput(nil,
410 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
411 *consensus.BTMAssetID, 10000000000, 0, nil),
412 types.NewSpendInput(nil,
413 bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
414 testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 1, nil),
416 Outputs: []*types.TxOutput{
417 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
418 types.NewIntraChainOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 5000000000, testutil.MustDecodeHexString("6a")),
425 category: "input output unbalance",
426 desc: "use retired utxo",
427 insts: []*signingInst{singleSignInst, singleSignInst},
428 txData: types.TxData{
430 Inputs: []*types.TxInput{
431 types.NewSpendInput(nil,
432 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
433 *consensus.BTMAssetID, 10000000000, 0, testutil.MustDecodeHexString("6a")),
435 Outputs: []*types.TxOutput{
436 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
443 category: "input output unbalance",
444 desc: "input utxo is zero",
445 insts: []*signingInst{singleSignInst},
446 txData: types.TxData{
448 Inputs: []*types.TxInput{
449 types.NewSpendInput(nil,
450 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
451 *consensus.BTMAssetID, 0, 0, nil),
453 Outputs: []*types.TxOutput{
454 types.NewIntraChainOutput(*consensus.BTMAssetID, 0, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
461 category: "input output unbalance",
462 desc: "no btm input",
463 txData: types.TxData{
465 Inputs: []*types.TxInput{},
466 Outputs: []*types.TxOutput{
467 types.NewIntraChainOutput(*consensus.BTMAssetID, 10, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
474 category: "overflow",
475 desc: "spend btm input overflow",
476 insts: []*signingInst{singleSignInst, singleSignInst},
477 txData: types.TxData{
479 Inputs: []*types.TxInput{
480 types.NewSpendInput(nil,
481 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
482 *consensus.BTMAssetID, math.MaxUint64, 0, nil),
483 types.NewSpendInput(nil,
484 bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
485 *consensus.BTMAssetID, 10000000000, 1, nil),
487 Outputs: []*types.TxOutput{
488 types.NewIntraChainOutput(*consensus.BTMAssetID, 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
495 category: "overflow",
496 desc: "spend non btm input overflow",
497 insts: []*signingInst{singleSignInst, singleSignInst, singleSignInst},
498 txData: types.TxData{
500 Inputs: []*types.TxInput{
501 types.NewSpendInput(nil,
502 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
503 testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), math.MaxInt64, 0, nil),
504 types.NewSpendInput(nil,
505 bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
506 testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 100, 0, nil),
507 types.NewSpendInput(nil,
508 bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
509 *consensus.BTMAssetID, 10000000000, 1, nil),
511 Outputs: []*types.TxOutput{
512 types.NewIntraChainOutput(*consensus.BTMAssetID, 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
513 types.NewIntraChainOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 100, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
520 category: "overflow",
521 desc: "issuance non btm input overflow",
522 insts: []*signingInst{singleSignInst, singleSignInst, singleSignInst},
523 txData: types.TxData{
525 Inputs: []*types.TxInput{
526 types.NewSpendInput(nil,
527 bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
528 *consensus.BTMAssetID, 10000000000, 1, nil),
529 types.NewIssuanceInput( // assetID: 97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f
530 testutil.MustDecodeHexString("fd0aec4229deb281"),
534 testutil.MustDecodeHexString("e8f301f7bd3b1e4ca853b15559b3a253a4f5f9c7efba233ab0f6896bec23adc6a816c350e08f6b8ac5bc23eb5720173f9190805328af581f34a7fe561358d100"),
536 testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"),
538 types.NewIssuanceInput( // assetID: 97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f
539 testutil.MustDecodeHexString("fd0aec4229deb281"),
543 testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"),
546 Outputs: []*types.TxOutput{
547 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
548 types.NewIntraChainOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
555 category: "overflow",
556 desc: "sum of spend and issuance non btm input overflow",
557 insts: []*signingInst{singleSignInst, singleSignInst, singleSignInst},
558 txData: types.TxData{
560 Inputs: []*types.TxInput{
561 types.NewSpendInput(nil,
562 bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
563 *consensus.BTMAssetID, 10000000000, 1, nil),
564 types.NewIssuanceInput( // assetID: 97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f
565 testutil.MustDecodeHexString("fd0aec4229deb281"),
569 testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"),
571 types.NewSpendInput(nil,
572 bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
573 testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 100, 0, nil),
575 Outputs: []*types.TxOutput{
576 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
577 types.NewIntraChainOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 100, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
584 category: "overflow",
585 desc: "spend btm output overflow",
586 insts: []*signingInst{singleSignInst, singleSignInst},
587 txData: types.TxData{
589 Inputs: []*types.TxInput{
590 types.NewSpendInput(nil,
591 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
592 *consensus.BTMAssetID, 10000000000, 0, nil),
594 Outputs: []*types.TxOutput{
595 types.NewIntraChainOutput(*consensus.BTMAssetID, math.MaxUint64, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
602 category: "overflow",
603 desc: "retire btm output overflow",
604 insts: []*signingInst{singleSignInst, singleSignInst},
605 txData: types.TxData{
607 Inputs: []*types.TxInput{
608 types.NewSpendInput(nil,
609 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
610 *consensus.BTMAssetID, 10000000000, 0, nil),
612 Outputs: []*types.TxOutput{
613 types.NewIntraChainOutput(*consensus.BTMAssetID, math.MaxUint64, testutil.MustDecodeHexString("6a")),
620 category: "overflow",
621 desc: "non btm output overflow",
622 insts: []*signingInst{singleSignInst, singleSignInst},
623 txData: types.TxData{
625 Inputs: []*types.TxInput{
626 types.NewSpendInput(nil,
627 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
628 *consensus.BTMAssetID, 10000000000, 0, nil),
629 types.NewSpendInput(nil,
630 bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
631 testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 1, nil),
633 Outputs: []*types.TxOutput{
634 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
635 types.NewIntraChainOutput(*consensus.BTMAssetID, math.MaxUint64, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
642 category: "overflow",
643 desc: "retire non btm output overflow",
644 insts: []*signingInst{singleSignInst, singleSignInst},
645 txData: types.TxData{
647 Inputs: []*types.TxInput{
648 types.NewSpendInput(nil,
649 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
650 *consensus.BTMAssetID, 10000000000, 0, nil),
651 types.NewSpendInput(nil,
652 bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
653 testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 1, nil),
655 Outputs: []*types.TxOutput{
656 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
657 types.NewIntraChainOutput(*consensus.BTMAssetID, math.MaxUint64, testutil.MustDecodeHexString("6a")),
664 category: "overflow",
665 desc: "output with over range amount but sum in equal",
666 insts: []*signingInst{singleSignInst, singleSignInst},
667 txData: types.TxData{
669 Inputs: []*types.TxInput{
670 types.NewSpendInput(nil,
671 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
672 *consensus.BTMAssetID, 100000000, 0, nil),
674 Outputs: []*types.TxOutput{
675 types.NewIntraChainOutput(*consensus.BTMAssetID, 18446744073609551616, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
676 types.NewIntraChainOutput(*consensus.BTMAssetID, 18446744073609551616, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
677 types.NewIntraChainOutput(*consensus.BTMAssetID, 290000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
684 category: "verify signature fail",
685 desc: "btm single sign",
686 insts: []*signingInst{singleSignInst},
687 txData: types.TxData{
689 Inputs: []*types.TxInput{
690 types.NewSpendInput(nil,
691 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
692 *consensus.BTMAssetID, 10000000000, 0, testutil.MustDecodeHexString("00140876db6ca8f4542a836f0edd42b87d095d081182")), // wrong control program
694 Outputs: []*types.TxOutput{
695 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
702 category: "verify signature fail",
703 desc: "btm multi sign",
704 insts: []*signingInst{multiSignInst},
705 txData: types.TxData{
707 Inputs: []*types.TxInput{
708 types.NewSpendInput(nil,
709 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
710 *consensus.BTMAssetID, 10000000000, 0, testutil.MustDecodeHexString("00200824e931fb806bd77fdcd291aad3bd0a4493443a4120062bd659e64a3e0bac66")), // wrong control program
712 Outputs: []*types.TxOutput{
713 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
720 category: "verify signature fail",
721 desc: "spend non btm single sign",
722 insts: []*signingInst{singleSignInst, singleSignInst},
723 txData: types.TxData{
725 Inputs: []*types.TxInput{
726 types.NewSpendInput(nil,
727 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
728 *consensus.BTMAssetID, 10000000000, 0, nil),
729 types.NewSpendInput(nil,
730 bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
731 testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 1, testutil.MustDecodeHexString("00140876db6ca8f4542a836f0edd42b87d095d081182")), // wrong control program
733 Outputs: []*types.TxOutput{
734 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
735 types.NewIntraChainOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
742 category: "verify signature fail",
743 desc: "spend non btm multi sign",
744 insts: []*signingInst{singleSignInst, multiSignInst},
745 txData: types.TxData{
747 Inputs: []*types.TxInput{
748 types.NewSpendInput(nil,
749 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
750 *consensus.BTMAssetID, 10000000000, 0, nil),
751 types.NewSpendInput(nil,
752 bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
753 testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 1, testutil.MustDecodeHexString("00140876db6ca8f4542a836f0edd42b87d095d081182")), // wrong control program
755 Outputs: []*types.TxOutput{
756 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
757 types.NewIntraChainOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
764 category: "verify signature fail",
765 desc: "issuance non btm single sign",
766 insts: []*signingInst{singleSignInst, multiSignInst},
767 txData: types.TxData{
769 Inputs: []*types.TxInput{
770 types.NewSpendInput(nil,
771 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
772 *consensus.BTMAssetID, 10000000000, 0, nil),
773 types.NewIssuanceInput(
774 testutil.MustDecodeHexString("fd0aec4229deb281"),
776 // wrong issuance program
777 testutil.MustDecodeHexString("ae20c38173d800e62f63bd08cfaa9bc905e4a34a61ad841d7ad6c70ead0fb48196995151ad"),
782 Outputs: []*types.TxOutput{
783 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
784 types.NewIntraChainOutput(testutil.MustDecodeAsset("bf5f8da2334590ee095148ccdcf4d806b26a47a6d9e9e857ef6c2de79aee4f14"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
791 category: "verify signature fail",
792 desc: "issuance non btm multi sign",
793 insts: []*signingInst{singleSignInst, multiSignInst},
794 txData: types.TxData{
796 Inputs: []*types.TxInput{
797 types.NewSpendInput(nil,
798 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
799 *consensus.BTMAssetID, 10000000000, 0, nil),
800 types.NewIssuanceInput(
801 testutil.MustDecodeHexString("fd0aec4229deb281"),
803 // wrong issuance program
804 testutil.MustDecodeHexString("ae20ce8639c5dc70cb2b12f89a057670602eb013fc54a10ce22bd4691c62cf546b7b2081bdd879bcbce7f58e1731841c6b3deac242efa00e75124fe559fa531c0c5bb820b40b6eec74288ee4bae67191f135512454b52640cfd7be95dc84be0f02281dce20247b6e6f9230a987ef61c66820268e7b766d28c1ce7aa2c550b34e294167f340205096211460415888768a48b121013711aa711634bb9ff7341a7bd072c31525875355ad"),
806 testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"),
809 Outputs: []*types.TxOutput{
810 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
811 types.NewIntraChainOutput(testutil.MustDecodeAsset("776f0a421e9176a03061d388aff4ab3b1bcd32e53a090d593a466706c69e3d3f"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
818 category: "double spend",
819 desc: "btm asset double spend",
820 insts: []*signingInst{singleSignInst, singleSignInst},
821 txData: types.TxData{
823 Inputs: []*types.TxInput{
824 types.NewSpendInput(nil,
825 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
826 *consensus.BTMAssetID, 10000000000, 0, testutil.MustDecodeHexString("001420a1af4fc11399e6cd7253abf1bbd4d0af17daad")),
827 types.NewSpendInput(nil,
828 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
829 *consensus.BTMAssetID, 10000000000, 0, testutil.MustDecodeHexString("001420a1af4fc11399e6cd7253abf1bbd4d0af17daad")),
831 Outputs: []*types.TxOutput{
832 types.NewIntraChainOutput(*consensus.BTMAssetID, 19000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
839 category: "double spend",
840 desc: "non btm asset double spend",
841 insts: []*signingInst{singleSignInst, singleSignInst, singleSignInst},
842 txData: types.TxData{
844 Inputs: []*types.TxInput{
845 types.NewSpendInput(nil,
846 bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
847 *consensus.BTMAssetID, 10000000000, 0, nil),
850 bc.Hash{V0: 3485387979411255237, V1: 15603105575416882039, V2: 5974145557334619041, V3: 16513948410238218452},
851 testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 0, testutil.MustDecodeHexString("001420a1af4fc11399e6cd7253abf1bbd4d0af17daad")),
854 bc.Hash{V0: 3485387979411255237, V1: 15603105575416882039, V2: 5974145557334619041, V3: 16513948410238218452},
855 testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 0, testutil.MustDecodeHexString("001420a1af4fc11399e6cd7253abf1bbd4d0af17daad")),
857 Outputs: []*types.TxOutput{
858 types.NewIntraChainOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
859 types.NewIntraChainOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 20000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")),
867 for i, c := range cases {
868 mockCtrlProgram(c.txData, c.insts)
870 c.txData.SerializedSize = 1
872 tx := types.NewTx(c.txData)
873 mockSignTx(tx, c.insts)
874 bcTx := types.MapTx(&c.txData)
876 gasStatus, err := validation.ValidateTx(bcTx, &bc.Block{
877 BlockHeader: &bc.BlockHeader{Height: 1},
878 Transactions: []*bc.Tx{bcTx},
880 if !c.err && err != nil {
881 t.Errorf("case #%d (%s) expect no error, got error %s", i, c.desc, err)
884 if c.err && err == nil {
885 t.Errorf("case #%d (%s) expect error, got no error", i, c.desc)
888 if c.gasValid != gasStatus.GasValid {
889 t.Errorf("case #%d (%s) got GasValid %t, want %t", i, c.desc, gasStatus.GasValid, c.gasValid)
894 type signingInst struct {
898 ctrlProgramIndex uint64
902 func mockCtrlProgram(txData types.TxData, insts []*signingInst) {
903 for i, input := range txData.Inputs {
904 _, xPubs := mustGetRootKeys(insts[i].rootPrvKeys)
906 switch inp := input.TypedInput.(type) {
907 case *types.SpendInput:
908 if inp.ControlProgram != nil {
911 acc := &account.Account{Signer: &signers.Signer{KeyIndex: insts[i].keyIndex, DeriveRule: signers.BIP0044, XPubs: xPubs, Quorum: insts[i].quorum}}
912 program, err := account.CreateCtrlProgram(acc, insts[i].ctrlProgramIndex, insts[i].change)
916 inp.ControlProgram = program.ControlProgram
917 case *types.IssuanceInput:
918 if inp.IssuanceProgram != nil {
921 assetSigner, err := signers.Create("asset", xPubs, insts[i].quorum, insts[i].keyIndex, signers.BIP0032)
926 path := signers.GetBip0032Path(assetSigner, signers.AssetKeySpace)
927 derivedXPubs := chainkd.DeriveXPubs(assetSigner.XPubs, path)
928 derivedPKs := chainkd.XPubKeys(derivedXPubs)
930 issuanceProg, err := vmutil.P2SPMultiSigProgramWithHeight(derivedPKs, insts[i].quorum, 0)
935 inp.IssuanceProgram = issuanceProg
940 func mockSignTx(tx *types.Tx, insts []*signingInst) {
941 for i, input := range tx.TxData.Inputs {
942 if input.Arguments() != nil {
945 var arguments [][]byte
947 switch inp := input.TypedInput.(type) {
948 case *types.SpendInput:
949 path, err := signers.Path(&signers.Signer{KeyIndex: inst.keyIndex, DeriveRule: signers.BIP0044}, signers.AccountKeySpace, inst.change, inst.ctrlProgramIndex)
954 xPrvs, xPubs := mustGetRootKeys(inst.rootPrvKeys)
955 for _, xPrv := range xPrvs {
956 childPrv := xPrv.Derive(path)
957 sigHashBytes := tx.SigHash(uint32(i)).Byte32()
958 arguments = append(arguments, childPrv.Sign(sigHashBytes[:]))
962 childPrv := xPrvs[0].Derive(path)
963 derivePK := childPrv.XPub()
964 arguments = append(arguments, derivePK.PublicKey())
966 derivedXPubs := chainkd.DeriveXPubs(xPubs, path)
967 derivedPKs := chainkd.XPubKeys(derivedXPubs)
968 script, err := vmutil.P2SPMultiSigProgram(derivedPKs, inst.quorum)
973 arguments = append(arguments, script)
975 inp.Arguments = arguments
976 case *types.IssuanceInput:
977 path := signers.GetBip0032Path(&signers.Signer{KeyIndex: inst.keyIndex, DeriveRule: signers.BIP0032}, signers.AssetKeySpace)
978 xPrvs, _ := mustGetRootKeys(inst.rootPrvKeys)
979 for _, xPrv := range xPrvs {
980 childPrv := xPrv.Derive(path)
981 sigHashBytes := tx.SigHash(uint32(i)).Byte32()
982 arguments = append(arguments, childPrv.Sign(sigHashBytes[:]))
984 inp.Arguments = arguments
989 func mustGetRootKeys(prvs []string) ([]chainkd.XPrv, []chainkd.XPub) {
990 xPubs := make([]chainkd.XPub, len(prvs))
991 xPrvs := make([]chainkd.XPrv, len(prvs))
992 for i, xPrv := range prvs {
993 xPrvBytes, err := hex.DecodeString(xPrv)
998 if len(xPrvBytes) != 64 {
999 panic("the size of xPrv must 64")
1004 xPrvs[i] = chainkd.XPrv(dest)
1005 xPubs[i] = xPrvs[i].XPub()