github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/protocol/validation/test/tx_ugly_test.go (about) 1 package test 2 3 import ( 4 "encoding/hex" 5 "math" 6 "testing" 7 8 "github.com/bytom/bytom/account" 9 "github.com/bytom/bytom/blockchain/signers" 10 "github.com/bytom/bytom/consensus" 11 "github.com/bytom/bytom/crypto/ed25519/chainkd" 12 "github.com/bytom/bytom/protocol/bc" 13 "github.com/bytom/bytom/protocol/bc/types" 14 "github.com/bytom/bytom/protocol/validation" 15 "github.com/bytom/bytom/protocol/vm/vmutil" 16 "github.com/bytom/bytom/testutil" 17 ) 18 19 func TestValidateUglyTx(t *testing.T) { 20 singleSignInst := &signingInst{ 21 rootPrvKeys: []string{ 22 "38d2c44314c401b3ea7c23c54e12c36a527aee46a7f26b82443a46bf40583e439dea25de09b0018b35a741d8cd9f6ec06bc11db49762617485f5309ab72a12d4", 23 }, 24 quorum: 1, 25 keyIndex: 1, 26 ctrlProgramIndex: 1, 27 change: false, 28 } 29 multiSignInst := &signingInst{ 30 rootPrvKeys: []string{ 31 "a080aca2d9d7948d005c92d0729c618e56fb5551a52dfa04dc4caaf3c8b8a94c89a9795f5bbfd2b885ce7a9d3e3efa5386436c3681b21f9263a0b0a544346b48", 32 "105295324626e33bb7d8e8a57c6a0aa495346d7fc342a4891ece00424494cf48f75cefa0f8c61674a12238cfa711b4bc26cb22f38b6e2206c691b83943a58312", 33 "c02bb73d1aee56f8935fb7704f71f668eb37ec223baf5723b38a186669b465427d1bdbc2c4397c1259d12b6229aaf6154aaccdeb8addce3a780a1cbc1025ad25", 34 "a0c2225685e4c4439f12c264d1573db063ddbc929d4b8a3e1641e8abb4df504a56b1200b9925138d79febe6e1156fcfaf0d1878f25cbccc5db4c8fea55bde198", 35 "20d06d4fd261ab554e01104f019392f89566acace727e6bb6de4544aa3a6b248480232155332e6e5de10a62e4a9a4c1d9e3b7f9cb4fd196142ef1d080b8bbaec", 36 }, 37 quorum: 3, 38 keyIndex: 1, 39 ctrlProgramIndex: 1, 40 change: false, 41 } 42 cases := []struct { 43 category string 44 desc string 45 insts []*signingInst 46 txData types.TxData 47 gasValid bool 48 err bool 49 }{ 50 { 51 category: "fee insufficient", 52 desc: "sum of btm output greater than btm input", 53 insts: []*signingInst{singleSignInst}, 54 txData: types.TxData{ 55 Version: 1, 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), 60 }, 61 Outputs: []*types.TxOutput{ 62 types.NewTxOutput(*consensus.BTMAssetID, 10000000001, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 63 }, 64 }, 65 err: true, 66 gasValid: false, 67 }, 68 { 69 category: "fee insufficient", 70 desc: "sum of btm output equals to input btm", 71 insts: []*signingInst{singleSignInst}, 72 txData: types.TxData{ 73 Version: 1, 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), 78 }, 79 Outputs: []*types.TxOutput{ 80 types.NewTxOutput(*consensus.BTMAssetID, 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 81 }, 82 }, 83 err: true, 84 gasValid: false, 85 }, 86 { 87 category: "fee insufficient", 88 desc: "sum of btm input greater than btm output, but still insufficient", 89 insts: []*signingInst{singleSignInst}, 90 txData: types.TxData{ 91 Version: 1, 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), 96 }, 97 Outputs: []*types.TxOutput{ 98 types.NewTxOutput(*consensus.BTMAssetID, 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 99 }, 100 }, 101 err: true, 102 gasValid: false, 103 }, 104 { 105 category: "fee insufficient", 106 desc: "no btm input", 107 insts: []*signingInst{singleSignInst}, 108 txData: types.TxData{ 109 Version: 1, 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), 114 }, 115 Outputs: []*types.TxOutput{ 116 types.NewTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 117 }, 118 }, 119 err: true, 120 gasValid: true, 121 }, 122 { 123 category: "input output unbalance", 124 desc: "only has btm input, no output", 125 insts: []*signingInst{singleSignInst}, 126 txData: types.TxData{ 127 Version: 1, 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), 132 }, 133 Outputs: []*types.TxOutput{}, 134 }, 135 err: true, 136 gasValid: false, 137 }, 138 { 139 category: "input output unbalance", 140 desc: "issuance asset, no corresponding output", 141 insts: []*signingInst{singleSignInst, singleSignInst}, 142 txData: types.TxData{ 143 Version: 1, 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"), 150 10000000000, 151 nil, 152 nil, 153 testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"), 154 ), 155 }, 156 Outputs: []*types.TxOutput{ 157 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 158 }, 159 }, 160 err: true, 161 gasValid: false, 162 }, 163 { 164 category: "input output unbalance", 165 desc: "issuance asset A, output asset B", 166 insts: []*signingInst{singleSignInst, singleSignInst}, 167 txData: types.TxData{ 168 Version: 1, 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"), 175 10000000000, 176 nil, 177 nil, 178 testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"), 179 ), 180 }, 181 Outputs: []*types.TxOutput{ 182 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 183 types.NewTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707e"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 184 }, 185 }, 186 err: true, 187 gasValid: false, 188 }, 189 { 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{ 194 Version: 1, 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"), 201 10000000000, 202 nil, 203 nil, 204 testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"), 205 ), 206 }, 207 Outputs: []*types.TxOutput{ 208 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 209 types.NewTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 20000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 210 }, 211 }, 212 err: true, 213 gasValid: false, 214 }, 215 { 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{ 220 Version: 1, 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"), 227 10000000000, 228 nil, 229 nil, 230 testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"), 231 ), 232 }, 233 Outputs: []*types.TxOutput{ 234 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 235 types.NewTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 5000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 236 }, 237 }, 238 err: true, 239 gasValid: false, 240 }, 241 { 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{ 246 Version: 1, 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"), 253 10000000000, 254 nil, 255 nil, 256 testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"), 257 ), 258 }, 259 Outputs: []*types.TxOutput{ 260 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 261 types.NewTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 20000000000, testutil.MustDecodeHexString("6a")), 262 }, 263 }, 264 err: true, 265 gasValid: false, 266 }, 267 { 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{ 272 Version: 1, 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"), 279 10000000000, 280 nil, 281 nil, 282 testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"), 283 ), 284 }, 285 Outputs: []*types.TxOutput{ 286 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 287 types.NewTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 5000000000, testutil.MustDecodeHexString("6a")), 288 }, 289 }, 290 err: true, 291 gasValid: false, 292 }, 293 { 294 category: "input output unbalance", 295 desc: "spend asset A, no corresponding output", 296 insts: []*signingInst{singleSignInst, singleSignInst}, 297 txData: types.TxData{ 298 Version: 1, 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), 306 }, 307 Outputs: []*types.TxOutput{ 308 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 309 }, 310 }, 311 err: true, 312 gasValid: false, 313 }, 314 { 315 category: "input output unbalance", 316 desc: "spend asset A, output asset B", 317 insts: []*signingInst{singleSignInst, singleSignInst}, 318 txData: types.TxData{ 319 Version: 1, 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), 327 }, 328 Outputs: []*types.TxOutput{ 329 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 330 types.NewTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707e"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 331 }, 332 }, 333 err: true, 334 gasValid: false, 335 }, 336 { 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{ 341 Version: 1, 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), 349 }, 350 Outputs: []*types.TxOutput{ 351 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 352 types.NewTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 20000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 353 }, 354 }, 355 err: true, 356 gasValid: false, 357 }, 358 { 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{ 363 Version: 1, 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), 371 }, 372 Outputs: []*types.TxOutput{ 373 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 374 types.NewTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 5000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 375 }, 376 }, 377 err: true, 378 gasValid: false, 379 }, 380 { 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{ 385 Version: 1, 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), 393 }, 394 Outputs: []*types.TxOutput{ 395 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 396 types.NewTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 20000000000, testutil.MustDecodeHexString("6a")), 397 }, 398 }, 399 err: true, 400 gasValid: false, 401 }, 402 { 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{ 407 Version: 1, 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), 415 }, 416 Outputs: []*types.TxOutput{ 417 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 418 types.NewTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 5000000000, testutil.MustDecodeHexString("6a")), 419 }, 420 }, 421 err: true, 422 gasValid: false, 423 }, 424 { 425 category: "input output unbalance", 426 desc: "use retired utxo", 427 insts: []*signingInst{singleSignInst, singleSignInst}, 428 txData: types.TxData{ 429 Version: 1, 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")), 434 }, 435 Outputs: []*types.TxOutput{ 436 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 437 }, 438 }, 439 err: true, 440 gasValid: false, 441 }, 442 { 443 category: "input output unbalance", 444 desc: "input utxo is zero", 445 insts: []*signingInst{singleSignInst}, 446 txData: types.TxData{ 447 Version: 1, 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), 452 }, 453 Outputs: []*types.TxOutput{ 454 types.NewTxOutput(*consensus.BTMAssetID, 0, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 455 }, 456 }, 457 err: true, 458 gasValid: false, 459 }, 460 { 461 category: "input output unbalance", 462 desc: "no btm input", 463 txData: types.TxData{ 464 Version: 1, 465 Inputs: []*types.TxInput{}, 466 Outputs: []*types.TxOutput{ 467 types.NewTxOutput(*consensus.BTMAssetID, 10, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 468 }, 469 }, 470 err: true, 471 gasValid: false, 472 }, 473 { 474 category: "overflow", 475 desc: "spend btm input overflow", 476 insts: []*signingInst{singleSignInst, singleSignInst}, 477 txData: types.TxData{ 478 Version: 1, 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), 486 }, 487 Outputs: []*types.TxOutput{ 488 types.NewTxOutput(*consensus.BTMAssetID, 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 489 }, 490 }, 491 err: true, 492 gasValid: false, 493 }, 494 { 495 category: "overflow", 496 desc: "spend non btm input overflow", 497 insts: []*signingInst{singleSignInst, singleSignInst, singleSignInst}, 498 txData: types.TxData{ 499 Version: 1, 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), 510 }, 511 Outputs: []*types.TxOutput{ 512 types.NewTxOutput(*consensus.BTMAssetID, 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 513 types.NewTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 100, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 514 }, 515 }, 516 err: true, 517 gasValid: false, 518 }, 519 { 520 category: "overflow", 521 desc: "issuance non btm input overflow", 522 insts: []*signingInst{singleSignInst, singleSignInst, singleSignInst}, 523 txData: types.TxData{ 524 Version: 1, 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"), 531 math.MaxInt64, 532 nil, 533 [][]byte{ 534 testutil.MustDecodeHexString("e8f301f7bd3b1e4ca853b15559b3a253a4f5f9c7efba233ab0f6896bec23adc6a816c350e08f6b8ac5bc23eb5720173f9190805328af581f34a7fe561358d100"), 535 }, 536 testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"), 537 ), 538 types.NewIssuanceInput( // assetID: 97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f 539 testutil.MustDecodeHexString("fd0aec4229deb281"), 540 10000000000, 541 nil, 542 nil, 543 testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"), 544 ), 545 }, 546 Outputs: []*types.TxOutput{ 547 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 548 types.NewTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 549 }, 550 }, 551 err: true, 552 gasValid: false, 553 }, 554 { 555 category: "overflow", 556 desc: "sum of spend and issuance non btm input overflow", 557 insts: []*signingInst{singleSignInst, singleSignInst, singleSignInst}, 558 txData: types.TxData{ 559 Version: 1, 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"), 566 math.MaxInt64, 567 nil, 568 nil, 569 testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"), 570 ), 571 types.NewSpendInput(nil, 572 bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302}, 573 testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 100, 0, nil), 574 }, 575 Outputs: []*types.TxOutput{ 576 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 577 types.NewTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 100, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 578 }, 579 }, 580 err: true, 581 gasValid: false, 582 }, 583 { 584 category: "overflow", 585 desc: "spend btm output overflow", 586 insts: []*signingInst{singleSignInst, singleSignInst}, 587 txData: types.TxData{ 588 Version: 1, 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), 593 }, 594 Outputs: []*types.TxOutput{ 595 types.NewTxOutput(*consensus.BTMAssetID, math.MaxUint64, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 596 }, 597 }, 598 err: true, 599 gasValid: false, 600 }, 601 { 602 category: "overflow", 603 desc: "retire btm output overflow", 604 insts: []*signingInst{singleSignInst, singleSignInst}, 605 txData: types.TxData{ 606 Version: 1, 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), 611 }, 612 Outputs: []*types.TxOutput{ 613 types.NewTxOutput(*consensus.BTMAssetID, math.MaxUint64, testutil.MustDecodeHexString("6a")), 614 }, 615 }, 616 err: true, 617 gasValid: false, 618 }, 619 { 620 category: "overflow", 621 desc: "non btm output overflow", 622 insts: []*signingInst{singleSignInst, singleSignInst}, 623 txData: types.TxData{ 624 Version: 1, 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), 632 }, 633 Outputs: []*types.TxOutput{ 634 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 635 types.NewTxOutput(*consensus.BTMAssetID, math.MaxUint64, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 636 }, 637 }, 638 err: true, 639 gasValid: false, 640 }, 641 { 642 category: "overflow", 643 desc: "retire non btm output overflow", 644 insts: []*signingInst{singleSignInst, singleSignInst}, 645 txData: types.TxData{ 646 Version: 1, 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), 654 }, 655 Outputs: []*types.TxOutput{ 656 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 657 types.NewTxOutput(*consensus.BTMAssetID, math.MaxUint64, testutil.MustDecodeHexString("6a")), 658 }, 659 }, 660 err: true, 661 gasValid: false, 662 }, 663 { 664 category: "overflow", 665 desc: "output with over range amount but sum in equal", 666 insts: []*signingInst{singleSignInst, singleSignInst}, 667 txData: types.TxData{ 668 Version: 1, 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), 673 }, 674 Outputs: []*types.TxOutput{ 675 types.NewTxOutput(*consensus.BTMAssetID, 18446744073609551616, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 676 types.NewTxOutput(*consensus.BTMAssetID, 18446744073609551616, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 677 types.NewTxOutput(*consensus.BTMAssetID, 290000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 678 }, 679 }, 680 err: true, 681 gasValid: false, 682 }, 683 { 684 category: "verify signature fail", 685 desc: "btm single sign", 686 insts: []*signingInst{singleSignInst}, 687 txData: types.TxData{ 688 Version: 1, 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 693 }, 694 Outputs: []*types.TxOutput{ 695 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 696 }, 697 }, 698 err: true, 699 gasValid: false, 700 }, 701 { 702 category: "verify signature fail", 703 desc: "btm multi sign", 704 insts: []*signingInst{multiSignInst}, 705 txData: types.TxData{ 706 Version: 1, 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 711 }, 712 Outputs: []*types.TxOutput{ 713 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 714 }, 715 }, 716 err: true, 717 gasValid: false, 718 }, 719 { 720 category: "verify signature fail", 721 desc: "spend non btm single sign", 722 insts: []*signingInst{singleSignInst, singleSignInst}, 723 txData: types.TxData{ 724 Version: 1, 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 732 }, 733 Outputs: []*types.TxOutput{ 734 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 735 types.NewTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 736 }, 737 }, 738 err: true, 739 gasValid: true, 740 }, 741 { 742 category: "verify signature fail", 743 desc: "spend non btm multi sign", 744 insts: []*signingInst{singleSignInst, multiSignInst}, 745 txData: types.TxData{ 746 Version: 1, 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 754 }, 755 Outputs: []*types.TxOutput{ 756 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 757 types.NewTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 758 }, 759 }, 760 err: true, 761 gasValid: true, 762 }, 763 { 764 category: "verify signature fail", 765 desc: "issuance non btm single sign", 766 insts: []*signingInst{singleSignInst, multiSignInst}, 767 txData: types.TxData{ 768 Version: 1, 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"), 775 10000000000, 776 // wrong issuance program 777 testutil.MustDecodeHexString("ae20c38173d800e62f63bd08cfaa9bc905e4a34a61ad841d7ad6c70ead0fb48196995151ad"), 778 nil, 779 nil, 780 ), 781 }, 782 Outputs: []*types.TxOutput{ 783 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 784 types.NewTxOutput(testutil.MustDecodeAsset("bf5f8da2334590ee095148ccdcf4d806b26a47a6d9e9e857ef6c2de79aee4f14"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 785 }, 786 }, 787 err: true, 788 gasValid: true, 789 }, 790 { 791 category: "verify signature fail", 792 desc: "issuance non btm multi sign", 793 insts: []*signingInst{singleSignInst, multiSignInst}, 794 txData: types.TxData{ 795 Version: 1, 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"), 802 10000000000, 803 // wrong issuance program 804 testutil.MustDecodeHexString("ae20ce8639c5dc70cb2b12f89a057670602eb013fc54a10ce22bd4691c62cf546b7b2081bdd879bcbce7f58e1731841c6b3deac242efa00e75124fe559fa531c0c5bb820b40b6eec74288ee4bae67191f135512454b52640cfd7be95dc84be0f02281dce20247b6e6f9230a987ef61c66820268e7b766d28c1ce7aa2c550b34e294167f340205096211460415888768a48b121013711aa711634bb9ff7341a7bd072c31525875355ad"), 805 nil, 806 testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"), 807 ), 808 }, 809 Outputs: []*types.TxOutput{ 810 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 811 types.NewTxOutput(testutil.MustDecodeAsset("776f0a421e9176a03061d388aff4ab3b1bcd32e53a090d593a466706c69e3d3f"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 812 }, 813 }, 814 err: true, 815 gasValid: true, 816 }, 817 { 818 category: "double spend", 819 desc: "btm asset double spend", 820 insts: []*signingInst{singleSignInst, singleSignInst}, 821 txData: types.TxData{ 822 Version: 1, 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")), 830 }, 831 Outputs: []*types.TxOutput{ 832 types.NewTxOutput(*consensus.BTMAssetID, 19000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 833 }, 834 }, 835 err: true, 836 gasValid: true, 837 }, 838 { 839 category: "double spend", 840 desc: "non btm asset double spend", 841 insts: []*signingInst{singleSignInst, singleSignInst, singleSignInst}, 842 txData: types.TxData{ 843 Version: 1, 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), 848 types.NewSpendInput( 849 nil, 850 bc.Hash{V0: 3485387979411255237, V1: 15603105575416882039, V2: 5974145557334619041, V3: 16513948410238218452}, 851 testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 0, testutil.MustDecodeHexString("001420a1af4fc11399e6cd7253abf1bbd4d0af17daad")), 852 types.NewSpendInput( 853 nil, 854 bc.Hash{V0: 3485387979411255237, V1: 15603105575416882039, V2: 5974145557334619041, V3: 16513948410238218452}, 855 testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 0, testutil.MustDecodeHexString("001420a1af4fc11399e6cd7253abf1bbd4d0af17daad")), 856 }, 857 Outputs: []*types.TxOutput{ 858 types.NewTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 859 types.NewTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 20000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166")), 860 }, 861 }, 862 err: true, 863 gasValid: true, 864 }, 865 } 866 867 for i, c := range cases { 868 mockCtrlProgram(c.txData, c.insts) 869 870 c.txData.SerializedSize = 1 871 872 tx := types.NewTx(c.txData) 873 mockSignTx(tx, c.insts) 874 bcTx := types.MapTx(&c.txData) 875 876 gasStatus, err := validation.ValidateTx(bcTx, &bc.Block{ 877 BlockHeader: &bc.BlockHeader{Height: 1}, 878 Transactions: []*bc.Tx{bcTx}, 879 }) 880 if !c.err && err != nil { 881 t.Errorf("case #%d (%s) expect no error, got error %s", i, c.desc, err) 882 } 883 884 if c.err && err == nil { 885 t.Errorf("case #%d (%s) expect error, got no error", i, c.desc) 886 } 887 888 if c.gasValid != gasStatus.GasValid { 889 t.Errorf("case #%d (%s) got GasValid %t, want %t", i, c.desc, gasStatus.GasValid, c.gasValid) 890 } 891 } 892 } 893 894 type signingInst struct { 895 rootPrvKeys []string 896 quorum int 897 keyIndex uint64 898 ctrlProgramIndex uint64 899 change bool 900 } 901 902 func mockCtrlProgram(txData types.TxData, insts []*signingInst) { 903 for i, input := range txData.Inputs { 904 _, xPubs := mustGetRootKeys(insts[i].rootPrvKeys) 905 906 switch inp := input.TypedInput.(type) { 907 case *types.SpendInput: 908 if inp.ControlProgram != nil { 909 continue 910 } 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) 913 if err != nil { 914 panic(err) 915 } 916 inp.ControlProgram = program.ControlProgram 917 case *types.IssuanceInput: 918 if inp.IssuanceProgram != nil { 919 continue 920 } 921 assetSigner, err := signers.Create("asset", xPubs, insts[i].quorum, insts[i].keyIndex, signers.BIP0032) 922 if err != nil { 923 panic(err) 924 } 925 926 path := signers.GetBip0032Path(assetSigner, signers.AssetKeySpace) 927 derivedXPubs := chainkd.DeriveXPubs(assetSigner.XPubs, path) 928 derivedPKs := chainkd.XPubKeys(derivedXPubs) 929 930 issuanceProg, err := vmutil.P2SPMultiSigProgramWithHeight(derivedPKs, insts[i].quorum, 0) 931 if err != nil { 932 panic(err) 933 } 934 935 inp.IssuanceProgram = issuanceProg 936 } 937 } 938 } 939 940 func mockSignTx(tx *types.Tx, insts []*signingInst) { 941 for i, input := range tx.TxData.Inputs { 942 if input.Arguments() != nil { 943 continue 944 } 945 var arguments [][]byte 946 inst := insts[i] 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) 950 if err != nil { 951 panic(err) 952 } 953 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[:])) 959 } 960 961 if len(xPrvs) == 1 { 962 childPrv := xPrvs[0].Derive(path) 963 derivePK := childPrv.XPub() 964 arguments = append(arguments, derivePK.PublicKey()) 965 } else { 966 derivedXPubs := chainkd.DeriveXPubs(xPubs, path) 967 derivedPKs := chainkd.XPubKeys(derivedXPubs) 968 script, err := vmutil.P2SPMultiSigProgram(derivedPKs, inst.quorum) 969 if err != nil { 970 panic(err) 971 } 972 973 arguments = append(arguments, script) 974 } 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[:])) 983 } 984 inp.Arguments = arguments 985 } 986 } 987 } 988 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) 994 if err != nil { 995 panic(err) 996 } 997 998 if len(xPrvBytes) != 64 { 999 panic("the size of xPrv must 64") 1000 } 1001 1002 var dest [64]byte 1003 copy(dest[:], xPrv) 1004 xPrvs[i] = chainkd.XPrv(dest) 1005 xPubs[i] = xPrvs[i].XPub() 1006 } 1007 return xPrvs, xPubs 1008 }