| 1326 | TAPROOT_FLAGS = "P2SH,DERSIG,CHECKLOCKTIMEVERIFY,CHECKSEQUENCEVERIFY,WITNESS,NULLDUMMY,TAPROOT" |
| 1327 | |
| 1328 | def dump_json_test(tx, input_utxos, idx, success, failure): |
| 1329 | spender = input_utxos[idx].spender |
| 1330 | # Determine flags to dump |
| 1331 | flags = LEGACY_FLAGS if spender.comment.startswith("legacy/") or spender.comment.startswith("inactive/") else TAPROOT_FLAGS |
| 1332 | |
| 1333 | hash_genesis_block = bytearray(ser_uint256(g_genesis_hash)) |
| 1334 | hash_genesis_block.reverse() |
| 1335 | fields = [ |
| 1336 | ("tx", tx.serialize().hex()), |
| 1337 | ("prevouts", [x.output.serialize().hex() for x in input_utxos]), |
| 1338 | ("index", idx), |
| 1339 | ("flags", flags), |
| 1340 | ("comment", spender.comment), |
| 1341 | ("hash_genesis_block", hash_genesis_block.hex()) |
| 1342 | ] |
| 1343 | |
| 1344 | # The "final" field indicates that a spend should be always valid, even with more validation flags enabled |
| 1345 | # than the listed ones. Use standardness as a proxy for this (which gives a conservative underestimate). |
| 1346 | if spender.is_standard == Standard.ALL: |
| 1347 | fields.append(("final", True)) |
| 1348 | |
| 1349 | def dump_witness(wit): |
| 1350 | return OrderedDict([("scriptSig", wit[0].hex()), ("witness", [x.hex() for x in wit[1]])]) |
| 1351 | if success is not None: |
| 1352 | fields.append(("success", dump_witness(success))) |
| 1353 | if failure is not None: |
| 1354 | fields.append(("failure", dump_witness(failure))) |
| 1355 | |
| 1356 | # Write the dump to $TEST_DUMP_DIR/x/xyz... where x,y,z,... are the SHA1 sum of the dump (which makes the |
| 1357 | # file naming scheme compatible with fuzzing infrastructure). |
| 1358 | dump = json.dumps(OrderedDict(fields)) + ",\n" |
| 1359 | sha1 = hashlib.sha1(dump.encode("utf-8")).hexdigest() |
| 1360 | dirname = os.environ.get("TEST_DUMP_DIR", ".") + ("/%s" % sha1[0]) |
| 1361 | os.makedirs(dirname, exist_ok=True) |
| 1362 | with open(dirname + ("/%s" % sha1), 'w', encoding="utf8") as f: |
| 1363 | f.write(dump) |
| 1364 | |
| 1365 | # Data type to keep track of UTXOs, where they were created, and how to spend them. |
| 1366 | UTXOData = namedtuple('UTXOData', 'outpoint,output,spender') |