tx-engine 0.11.2__tar.gz → 0.11.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. tx_engine-0.11.4/.githooks/pre-commit +112 -0
  2. {tx_engine-0.11.2 → tx_engine-0.11.4}/.github/workflows/CI.yml +42 -22
  3. {tx_engine-0.11.2 → tx_engine-0.11.4}/.github/workflows/on_push.yml +56 -12
  4. {tx_engine-0.11.2 → tx_engine-0.11.4}/Cargo.lock +38 -25
  5. {tx_engine-0.11.2 → tx_engine-0.11.4}/Cargo.toml +11 -2
  6. {tx_engine-0.11.2 → tx_engine-0.11.4}/PKG-INFO +1 -1
  7. {tx_engine-0.11.2 → tx_engine-0.11.4}/docs/Development.md +30 -0
  8. {tx_engine-0.11.2 → tx_engine-0.11.4}/docs/Releases.md +2 -0
  9. tx_engine-0.11.4/python/src/tests/test_woc_balance.py +63 -0
  10. tx_engine-0.11.4/python/src/tests/test_woc_interface.py +83 -0
  11. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tx_engine/interface/woc.py +79 -21
  12. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tx_engine/interface/woc_interface.py +16 -6
  13. tx_engine-0.11.4/src/interface/woc_interface.rs +854 -0
  14. tx_engine-0.11.2/python/src/tests/test_woc_interface.py +0 -47
  15. tx_engine-0.11.2/src/interface/woc_interface.rs +0 -361
  16. {tx_engine-0.11.2 → tx_engine-0.11.4}/.github/dependabot.yml +0 -0
  17. {tx_engine-0.11.2 → tx_engine-0.11.4}/.gitignore +0 -0
  18. {tx_engine-0.11.2 → tx_engine-0.11.4}/LICENSE +0 -0
  19. {tx_engine-0.11.2 → tx_engine-0.11.4}/LICENSE-rust-sv +0 -0
  20. {tx_engine-0.11.2 → tx_engine-0.11.4}/README-chain-gang.md +0 -0
  21. {tx_engine-0.11.2 → tx_engine-0.11.4}/README-pypi.md +0 -0
  22. {tx_engine-0.11.2 → tx_engine-0.11.4}/README.md +0 -0
  23. {tx_engine-0.11.2 → tx_engine-0.11.4}/docs/BIP-32-Python.md +0 -0
  24. {tx_engine-0.11.2 → tx_engine-0.11.4}/docs/BIP-32.md +0 -0
  25. {tx_engine-0.11.2 → tx_engine-0.11.4}/docs/Chronicle-Python.md +0 -0
  26. {tx_engine-0.11.2 → tx_engine-0.11.4}/docs/Chronicle.md +0 -0
  27. {tx_engine-0.11.2 → tx_engine-0.11.4}/docs/Python-API.md +0 -0
  28. {tx_engine-0.11.2 → tx_engine-0.11.4}/docs/README-chain-gang.md +0 -0
  29. {tx_engine-0.11.2 → tx_engine-0.11.4}/docs/README.md +0 -0
  30. {tx_engine-0.11.2 → tx_engine-0.11.4}/docs/Regtest.md +0 -0
  31. {tx_engine-0.11.2 → tx_engine-0.11.4}/docs/Requirements +0 -0
  32. {tx_engine-0.11.2 → tx_engine-0.11.4}/docs/diagrams/keys.png +0 -0
  33. {tx_engine-0.11.2 → tx_engine-0.11.4}/docs/diagrams/keys.puml +0 -0
  34. {tx_engine-0.11.2 → tx_engine-0.11.4}/docs/diagrams/overview.png +0 -0
  35. {tx_engine-0.11.2 → tx_engine-0.11.4}/docs/diagrams/overview.puml +0 -0
  36. {tx_engine-0.11.2 → tx_engine-0.11.4}/docs/diagrams/python_classes.png +0 -0
  37. {tx_engine-0.11.2 → tx_engine-0.11.4}/docs/diagrams/python_classes.puml +0 -0
  38. {tx_engine-0.11.2 → tx_engine-0.11.4}/pyproject.toml +0 -0
  39. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/README.md +0 -0
  40. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/lint.sh +0 -0
  41. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/requirements.txt +0 -0
  42. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tests/README.md +0 -0
  43. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tests/test_bit_twiddling.py +0 -0
  44. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tests/test_bsv.py +0 -0
  45. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tests/test_chronicle_context.py +0 -0
  46. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tests/test_chronicle_opcodes.py +0 -0
  47. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tests/test_chronicle_tx_validate.py +0 -0
  48. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tests/test_debug.py +0 -0
  49. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tests/test_ec.py +0 -0
  50. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tests/test_fed.py +0 -0
  51. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tests/test_hd_wallet.py +0 -0
  52. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tests/test_if.py +0 -0
  53. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tests/test_interface.py +0 -0
  54. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tests/test_op.py +0 -0
  55. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tests/test_parse.py +0 -0
  56. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tests/test_rpc_interface.py +0 -0
  57. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tests/test_script.py +0 -0
  58. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tests/test_sighash.py +0 -0
  59. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tests/test_sign.py +0 -0
  60. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tests/test_tx.py +0 -0
  61. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tests/test_verify_script.py +0 -0
  62. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tests/test_wallet.py +0 -0
  63. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tests/test_wif_from_pw_nonce.py +0 -0
  64. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tests/test_woc.py +0 -0
  65. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tx_engine/__init__.py +0 -0
  66. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tx_engine/engine/__init__.py +0 -0
  67. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tx_engine/engine/context.py +0 -0
  68. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tx_engine/engine/cryptography_utils.py +0 -0
  69. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tx_engine/engine/engine_types.py +0 -0
  70. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tx_engine/engine/op_code_names.py +0 -0
  71. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tx_engine/engine/op_codes.py +0 -0
  72. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tx_engine/engine/util.py +0 -0
  73. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tx_engine/interface/__init__.py +0 -0
  74. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tx_engine/interface/blockchain_interface.py +0 -0
  75. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tx_engine/interface/interface_factory.py +0 -0
  76. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tx_engine/interface/mock_interface.py +0 -0
  77. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tx_engine/interface/rpc_interface.py +0 -0
  78. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tx_engine/interface/verify_script.py +0 -0
  79. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tx_engine/tx/__init__.py +0 -0
  80. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/src/tx_engine/tx/sighash.py +0 -0
  81. {tx_engine-0.11.2 → tx_engine-0.11.4}/python/tests.sh +0 -0
  82. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/address/mod.rs +0 -0
  83. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/chronicle.rs +0 -0
  84. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/interface/blockchain_interface.rs +0 -0
  85. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/interface/mod.rs +0 -0
  86. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/interface/rpc_interface.rs +0 -0
  87. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/interface/test_interface.rs +0 -0
  88. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/interface/uaas_interface.rs +0 -0
  89. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/lib.rs +0 -0
  90. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/addr.rs +0 -0
  91. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/authch.rs +0 -0
  92. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/block.rs +0 -0
  93. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/block_header.rs +0 -0
  94. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/block_locator.rs +0 -0
  95. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/blocktxn.rs +0 -0
  96. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/cmpctblock.rs +0 -0
  97. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/createstrm.rs +0 -0
  98. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/fee_filter.rs +0 -0
  99. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/filter_add.rs +0 -0
  100. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/filter_load.rs +0 -0
  101. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/getblocktxn.rs +0 -0
  102. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/headers.rs +0 -0
  103. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/inv.rs +0 -0
  104. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/inv_vect.rs +0 -0
  105. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/merkle_block.rs +0 -0
  106. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/message.rs +0 -0
  107. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/message_header.rs +0 -0
  108. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/mod.rs +0 -0
  109. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/node_addr.rs +0 -0
  110. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/node_addr_ex.rs +0 -0
  111. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/out_point.rs +0 -0
  112. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/ping.rs +0 -0
  113. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/protoconf.rs +0 -0
  114. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/reject.rs +0 -0
  115. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/send_cmpct.rs +0 -0
  116. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/streamack.rs +0 -0
  117. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/tx.rs +0 -0
  118. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/tx_chronicle_validate.rs +0 -0
  119. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/tx_in.rs +0 -0
  120. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/tx_out.rs +0 -0
  121. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/messages/version.rs +0 -0
  122. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/network/mod.rs +0 -0
  123. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/network/network.rs +0 -0
  124. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/network/seed_iter.rs +0 -0
  125. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/peer/atomic_reader.rs +0 -0
  126. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/peer/mod.rs +0 -0
  127. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/peer/peer.rs +0 -0
  128. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/python/mod.rs +0 -0
  129. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/python/py_hd_wallet.rs +0 -0
  130. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/python/py_script.rs +0 -0
  131. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/python/py_stack.rs +0 -0
  132. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/python/py_tx.rs +0 -0
  133. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/python/py_wallet.rs +0 -0
  134. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/script/checker.rs +0 -0
  135. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/script/format.rs +0 -0
  136. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/script/interpreter/eval.rs +0 -0
  137. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/script/interpreter/mod.rs +0 -0
  138. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/script/interpreter/multisig.rs +0 -0
  139. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/script/interpreter/push.rs +0 -0
  140. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/script/interpreter/rules.rs +0 -0
  141. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/script/interpreter/script_code.rs +0 -0
  142. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/script/interpreter/tests.rs +0 -0
  143. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/script/mod.rs +0 -0
  144. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/script/op_codes.rs +0 -0
  145. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/script/stack.rs +0 -0
  146. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/test_util.rs +0 -0
  147. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/transaction/mod.rs +0 -0
  148. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/transaction/p2pkh.rs +0 -0
  149. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/transaction/sighash.rs +0 -0
  150. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/util/bits.rs +0 -0
  151. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/util/bloom_filter.rs +0 -0
  152. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/util/bounded_read.rs +0 -0
  153. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/util/errors.rs +0 -0
  154. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/util/future.rs +0 -0
  155. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/util/hash160.rs +0 -0
  156. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/util/hash256.rs +0 -0
  157. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/util/latch.rs +0 -0
  158. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/util/mod.rs +0 -0
  159. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/util/rx.rs +0 -0
  160. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/util/serdes.rs +0 -0
  161. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/util/sha1.rs +0 -0
  162. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/util/sha256.rs +0 -0
  163. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/util/var_int.rs +0 -0
  164. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/wallet/base58_checksum.rs +0 -0
  165. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/wallet/extended_key.rs +0 -0
  166. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/wallet/hd_wallet.rs +0 -0
  167. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/wallet/hd_watch_wallet.rs +0 -0
  168. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/wallet/mnemonic.rs +0 -0
  169. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/wallet/mod.rs +0 -0
  170. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/wallet/wallet.rs +0 -0
  171. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/wallet/wordlists/chinese_simplified.txt +0 -0
  172. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/wallet/wordlists/chinese_traditional.txt +0 -0
  173. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/wallet/wordlists/english.txt +0 -0
  174. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/wallet/wordlists/french.txt +0 -0
  175. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/wallet/wordlists/italian.txt +0 -0
  176. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/wallet/wordlists/japanese.txt +0 -0
  177. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/wallet/wordlists/korean.txt +0 -0
  178. {tx_engine-0.11.2 → tx_engine-0.11.4}/src/wallet/wordlists/spanish.txt +0 -0
  179. {tx_engine-0.11.2 → tx_engine-0.11.4}/tests/hostile_lengths.rs +0 -0
  180. {tx_engine-0.11.2 → tx_engine-0.11.4}/tests/regtest_p2p.rs +0 -0
  181. {tx_engine-0.11.2 → tx_engine-0.11.4}/tools/README.md +0 -0
  182. {tx_engine-0.11.2 → tx_engine-0.11.4}/tools/dbg.py +0 -0
  183. {tx_engine-0.11.2 → tx_engine-0.11.4}/tools/generate_key.py +0 -0
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env python3
2
+ """Reject workflow YAML that GitHub Actions would refuse to run.
3
+
4
+ A duplicate mapping key is invalid YAML, but most loaders silently keep the
5
+ last value, so a workflow can look correct locally and behave correctly when
6
+ read by anything forgiving. GitHub does not forgive it: it rejects the file
7
+ and the run ends in 0s with no jobs, no annotations, and only "This run
8
+ likely failed because of a workflow file issue" to go on. CI cannot warn you
9
+ either, because the workflow that would have told you is the broken one.
10
+
11
+ Checks the staged content of .github/workflows/*.yml, not the working tree,
12
+ so a fixed-but-unstaged file still fails.
13
+
14
+ Run directly with paths to check files outside a commit:
15
+
16
+ .githooks/pre-commit .github/workflows/on_push.yml
17
+ """
18
+ import subprocess
19
+ import sys
20
+
21
+ WORKFLOW_DIR = ".github/workflows"
22
+ SUFFIXES = (".yml", ".yaml")
23
+
24
+
25
+ def staged_workflows():
26
+ """Paths of staged, still-present workflow files."""
27
+ out = subprocess.run(
28
+ ["git", "diff", "--cached", "--name-only", "--diff-filter=ACMR"],
29
+ capture_output=True, text=True, check=True,
30
+ ).stdout
31
+ return [
32
+ p for p in out.splitlines()
33
+ if p.startswith(WORKFLOW_DIR + "/") and p.endswith(SUFFIXES)
34
+ ]
35
+
36
+
37
+ def staged_content(path):
38
+ """The staged bytes for `path`, which may differ from the working tree."""
39
+ return subprocess.run(
40
+ ["git", "show", f":{path}"],
41
+ capture_output=True, check=True,
42
+ ).stdout
43
+
44
+
45
+ def check(path, content):
46
+ """Return an error string, or None when the file is fine."""
47
+ import yaml
48
+
49
+ class Strict(yaml.SafeLoader):
50
+ pass
51
+
52
+ def no_duplicate_keys(loader, node, deep=False):
53
+ seen = set()
54
+ for key_node, _ in node.value:
55
+ key = loader.construct_object(key_node, deep=deep)
56
+ if key in seen:
57
+ raise yaml.constructor.ConstructorError(
58
+ None, None, f"duplicate key {key!r}", key_node.start_mark
59
+ )
60
+ seen.add(key)
61
+ return yaml.constructor.SafeConstructor.construct_mapping(loader, node, deep)
62
+
63
+ Strict.add_constructor(
64
+ yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, no_duplicate_keys
65
+ )
66
+ try:
67
+ yaml.load(content, Strict)
68
+ except yaml.YAMLError as e:
69
+ return str(e)
70
+ return None
71
+
72
+
73
+ def main(argv):
74
+ try:
75
+ import yaml # noqa: F401
76
+ except ImportError:
77
+ # Skipping beats blocking a commit over a missing dev dependency, but
78
+ # say so rather than passing silently
79
+ print(
80
+ "pre-commit: PyYAML not installed, skipping the workflow YAML check.\n"
81
+ " pip install pyyaml to enable it.",
82
+ file=sys.stderr,
83
+ )
84
+ return 0
85
+
86
+ if argv:
87
+ targets = [(p, open(p, "rb").read()) for p in argv]
88
+ else:
89
+ targets = [(p, staged_content(p)) for p in staged_workflows()]
90
+
91
+ failed = False
92
+ for path, content in targets:
93
+ error = check(path, content)
94
+ if error:
95
+ if not failed:
96
+ print("pre-commit: invalid workflow YAML\n", file=sys.stderr)
97
+ print(f" {path}:\n{error}\n", file=sys.stderr)
98
+ failed = True
99
+
100
+ if failed:
101
+ print(
102
+ "GitHub Actions rejects these outright: the run ends in 0s with no\n"
103
+ "jobs and no useful error. Fix them, or commit with --no-verify if\n"
104
+ "you are certain.",
105
+ file=sys.stderr,
106
+ )
107
+ return 1
108
+ return 0
109
+
110
+
111
+ if __name__ == "__main__":
112
+ sys.exit(main(sys.argv[1:]))
@@ -4,6 +4,26 @@
4
4
  # maturin generate-ci github
5
5
  #
6
6
  name: CI
7
+ # CI runner image is pinned, not `ubuntu-latest`. That label migrates to Ubuntu 26
8
+ # from 19 October 2026 (actions/runner-images#14748), which would move the OS under
9
+ # every build on a date nobody chose. Pinning decouples the upgrade from that date
10
+ # so it happens deliberately, with someone watching. Tracked as CS-442.
11
+ #
12
+ # Now on 26.04 (CS-459). This file was held back at 24.04 while the rest moved
13
+ # (CS-444), because `manylinux: auto` fixes the wheel's glibc baseline and a
14
+ # raised floor would break downstream installs without failing anything here.
15
+ #
16
+ # Measured rather than reasoned about: the same build was run on both images
17
+ # and produced byte-identical wheel tags,
18
+ #
19
+ # ubuntu-24.04 (host glibc 2.39) -> ...-manylinux_2_17_x86_64.manylinux2014...
20
+ # ubuntu-26.04 (host glibc 2.43) -> ...-manylinux_2_17_x86_64.manylinux2014...
21
+ #
22
+ # because maturin-action builds inside quay.io/pypa/manylinux2014_x86_64 on
23
+ # both. The baseline comes from that container, not from the runner, so the
24
+ # host glibc never reaches the wheel. If `manylinux:` is ever changed or the
25
+ # container pinned differently, that reasoning no longer holds -- recheck by
26
+ # comparing wheel tags across images before moving this pin again.
7
27
 
8
28
  on:
9
29
  push:
@@ -34,21 +54,21 @@ jobs:
34
54
  strategy:
35
55
  matrix:
36
56
  platform:
37
- - runner: ubuntu-latest
57
+ - runner: ubuntu-26.04
38
58
  target: x86_64
39
- #- runner: ubuntu-latest
59
+ #- runner: ubuntu-26.04
40
60
  # target: x86
41
- #- runner: ubuntu-latest
61
+ #- runner: ubuntu-26.04
42
62
  # target: aarch64
43
- # - runner: ubuntu-latest
63
+ # - runner: ubuntu-26.04
44
64
  # target: armv7
45
- #- runner: ubuntu-latest
65
+ #- runner: ubuntu-26.04
46
66
  # target: s390x
47
- #- runner: ubuntu-latest
67
+ #- runner: ubuntu-26.04
48
68
  # target: ppc64le
49
69
  steps:
50
- - uses: actions/checkout@v4
51
- - uses: actions/setup-python@v5
70
+ - uses: actions/checkout@v7
71
+ - uses: actions/setup-python@v7
52
72
  with:
53
73
  python-version: '3.11'
54
74
  - name: Build wheels
@@ -59,7 +79,7 @@ jobs:
59
79
  sccache: 'true'
60
80
  manylinux: auto
61
81
  - name: Upload wheels
62
- uses: actions/upload-artifact@v4
82
+ uses: actions/upload-artifact@v7
63
83
  with:
64
84
  name: wheels-linux-${{ matrix.platform.target }}
65
85
  path: dist
@@ -75,8 +95,8 @@ jobs:
75
95
  - runner: windows-latest
76
96
  target: x86
77
97
  steps:
78
- - uses: actions/checkout@v4
79
- - uses: actions/setup-python@v5
98
+ - uses: actions/checkout@v7
99
+ - uses: actions/setup-python@v7
80
100
  with:
81
101
  python-version: '3.11'
82
102
  architecture: ${{ matrix.platform.target }}
@@ -87,7 +107,7 @@ jobs:
87
107
  args: --release --out dist --interpreter 3.11
88
108
  sccache: 'true'
89
109
  - name: Upload wheels
90
- uses: actions/upload-artifact@v4
110
+ uses: actions/upload-artifact@v7
91
111
  with:
92
112
  name: wheels-windows-${{ matrix.platform.target }}
93
113
  path: dist
@@ -103,8 +123,8 @@ jobs:
103
123
  - runner: macos-14
104
124
  target: aarch64
105
125
  steps:
106
- - uses: actions/checkout@v4
107
- - uses: actions/setup-python@v5
126
+ - uses: actions/checkout@v7
127
+ - uses: actions/setup-python@v7
108
128
  with:
109
129
  python-version: '3.11'
110
130
  - name: Build wheels
@@ -114,34 +134,34 @@ jobs:
114
134
  args: --release --out dist --interpreter 3.11
115
135
  sccache: 'true'
116
136
  - name: Upload wheels
117
- uses: actions/upload-artifact@v4
137
+ uses: actions/upload-artifact@v7
118
138
  with:
119
139
  name: wheels-macos-${{ matrix.platform.target }}
120
140
  path: dist
121
141
 
122
142
  sdist:
123
- runs-on: ubuntu-latest
143
+ runs-on: ubuntu-26.04
124
144
  if: "startsWith(github.ref, 'refs/tags/')"
125
145
  steps:
126
- - uses: actions/checkout@v4
146
+ - uses: actions/checkout@v7
127
147
  - name: Build sdist
128
148
  uses: PyO3/maturin-action@v1
129
149
  with:
130
150
  command: sdist
131
151
  args: --out dist
132
152
  - name: Upload sdist
133
- uses: actions/upload-artifact@v4
153
+ uses: actions/upload-artifact@v7
134
154
  with:
135
155
  name: wheels-sdist
136
156
  path: dist
137
157
 
138
158
  release:
139
159
  name: Release
140
- runs-on: ubuntu-latest
160
+ runs-on: ubuntu-26.04
141
161
  if: "startsWith(github.ref, 'refs/tags/')"
142
162
  needs: [linux, windows, macos, sdist]
143
163
  steps:
144
- - uses: actions/download-artifact@v4
164
+ - uses: actions/download-artifact@v8
145
165
  - name: Publish to PyPI
146
166
  uses: PyO3/maturin-action@v1
147
167
  env:
@@ -152,10 +172,10 @@ jobs:
152
172
 
153
173
  crates-io:
154
174
  name: Publish to crates.io
155
- runs-on: ubuntu-latest
175
+ runs-on: ubuntu-26.04
156
176
  if: "startsWith(github.ref, 'refs/tags/')"
157
177
  steps:
158
- - uses: actions/checkout@v4
178
+ - uses: actions/checkout@v7
159
179
  - name: Install Rust
160
180
  uses: actions-rust-lang/setup-rust-toolchain@v1
161
181
  with:
@@ -1,4 +1,33 @@
1
1
  name: On Push
2
+ # CI runner image is pinned, not `ubuntu-latest`. That label migrates to Ubuntu 26
3
+ # between 19 October and 19 November 2026 (actions/runner-images#14748), which
4
+ # would move the OS under every build on a date nobody chose. Pinning decouples
5
+ # the upgrade from that date so it happens deliberately (CS-442).
6
+ #
7
+ # Now on 26.04, moved ahead of the migration on the evidence of a trial rather
8
+ # than by the calendar (CS-444). This repo is where the trial actually found
9
+ # something: the first Ubuntu 26 run failed with
10
+ # `rust-lld: error: unable to find library -lpython3.12`, which looked exactly
11
+ # like an image incompatibility -- 24.04 ships Python 3.12, 26.04 ships 3.13 --
12
+ # and was not one. A 24.04 cache had been restored onto 26.04, carrying pyo3
13
+ # build output already resolved against 3.12. A control run with the cache
14
+ # disabled passed clean on 26.04.
15
+ #
16
+ # Hence `cache-key` below carries the image, and moving it is what busts the
17
+ # old cache rather than restoring it across the boundary. Keep it in step with
18
+ # `runs-on`: this is the repo that proves what happens when they disagree.
19
+ #
20
+ # CI.yml is now on 26.04 too (CS-459). It was held back while this file moved
21
+ # (CS-444), on the worry that `manylinux: auto` derives the wheel's glibc
22
+ # baseline from the runner, so a newer image could raise the minimum glibc of a
23
+ # published wheel and break downstream installs without failing anything here.
24
+ #
25
+ # That worry turned out to be misplaced, and it took a measurement rather than
26
+ # a tag to show it: the same build on both images produced identical wheel tags
27
+ # (manylinux_2_17), because maturin-action builds inside
28
+ # quay.io/pypa/manylinux2014_x86_64 either way. The baseline comes from that
29
+ # container, not from the runner, so host glibc -- 2.39 on 24.04, 2.43 on
30
+ # 26.04 -- never reaches the wheel.
2
31
  on: [push]
3
32
  permissions:
4
33
  contents: read
@@ -10,12 +39,12 @@ env:
10
39
  jobs:
11
40
  python-lint:
12
41
  name: Lint Python
13
- runs-on: ubuntu-latest
42
+ runs-on: ubuntu-26.04
14
43
  steps:
15
44
  - name: Checkout branch code
16
- uses: actions/checkout@v4
45
+ uses: actions/checkout@v7
17
46
  - name: Install Python
18
- uses: actions/setup-python@v5
47
+ uses: actions/setup-python@v7
19
48
  with:
20
49
  python-version: '3.12'
21
50
  cache: 'pip'
@@ -28,30 +57,43 @@ jobs:
28
57
 
29
58
  rust-test:
30
59
  name: Rust Tests
31
- runs-on: ubuntu-latest
60
+ runs-on: ubuntu-26.04
32
61
  steps:
33
62
  - name: Checkout branch code
34
- uses: actions/checkout@v4
63
+ uses: actions/checkout@v7
64
+ # `cargo test --all-features` enables `python`, which pulls in pyo3, but
65
+ # NOT `pyo3/extension-module` -- so unlike the maturin builds, the test
66
+ # binary links libpython directly. Without this step it linked whatever
67
+ # the runner image happened to ship, which is the only reason this job
68
+ # was sensitive to the image at all. 3.11 is the abi3 floor the crate
69
+ # targets and the interpreter the wheels are built with, so this tests
70
+ # against the oldest Python we claim to support.
71
+ - name: Install Python
72
+ uses: actions/setup-python@v7
73
+ with:
74
+ python-version: '3.11'
35
75
  - name: Install Rust
36
76
  uses: actions-rust-lang/setup-rust-toolchain@v1
37
77
  with:
38
78
  toolchain: stable
39
79
  cache: true
80
+ cache-key: ubuntu-26.04-py3.11
40
81
  - name: Rust Tests
41
82
  run: cargo test --all-features
42
83
 
43
84
  rust-clippy:
44
85
  name: Rust Clippy
45
- runs-on: ubuntu-latest
86
+ runs-on: ubuntu-26.04
46
87
  steps:
47
88
  - name: Checkout branch code
48
- uses: actions/checkout@v4
89
+ uses: actions/checkout@v7
49
90
  - name: Install Rust
50
91
  uses: actions-rust-lang/setup-rust-toolchain@v1
51
92
  with:
52
93
  toolchain: stable
53
94
  components: clippy
54
95
  cache: true
96
+ cache-key: ubuntu-26.04
55
97
  - name: Clippy
56
98
  run: cargo clippy --all-features --all-targets -- -D warnings
57
99
 
@@ -60,7 +102,7 @@ jobs:
60
102
  # that enables only some of them. This checks each set a dependent might pick.
61
103
  rust-features:
62
104
  name: Rust Features (${{ matrix.name }})
63
- runs-on: ubuntu-latest
105
+ runs-on: ubuntu-26.04
64
106
  strategy:
65
107
  fail-fast: false
66
108
  matrix:
@@ -75,27 +117,28 @@ jobs:
75
117
  args: "--no-default-features"
76
118
  steps:
77
119
  - name: Checkout branch code
78
- uses: actions/checkout@v4
120
+ uses: actions/checkout@v7
79
121
  - name: Install Rust
80
122
  uses: actions-rust-lang/setup-rust-toolchain@v1
81
123
  with:
82
124
  toolchain: stable
83
125
  cache: true
126
+ cache-key: ubuntu-26.04
84
127
  - name: Check
85
128
  run: cargo check --all-targets ${{ matrix.args }}
86
129
 
87
130
  python-test:
88
131
  name: Python Tests (${{ matrix.python-version }})
89
- runs-on: ubuntu-latest
132
+ runs-on: ubuntu-26.04
90
133
  strategy:
91
134
  fail-fast: false
92
135
  matrix:
93
136
  python-version: ['3.11', '3.12', '3.13', '3.14']
94
137
  steps:
95
138
  - name: Checkout branch code
96
- uses: actions/checkout@v4
139
+ uses: actions/checkout@v7
97
140
  - name: Install Python
98
- uses: actions/setup-python@v5
141
+ uses: actions/setup-python@v7
99
142
  with:
100
143
  python-version: ${{ matrix.python-version }}
101
144
  cache: 'pip'
@@ -104,6 +147,7 @@ jobs:
104
147
  with:
105
148
  toolchain: stable
106
149
  cache: true
150
+ cache-key: ubuntu-26.04
107
151
  - name: Clear wheel dir
108
152
  run: rm target/wheels/* | true
109
153
  - name: Maturin build
@@ -30,7 +30,7 @@ checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667"
30
30
  dependencies = [
31
31
  "proc-macro2",
32
32
  "quote",
33
- "syn 3.0.5",
33
+ "syn 3.0.6",
34
34
  ]
35
35
 
36
36
  [[package]]
@@ -136,9 +136,9 @@ checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
136
136
 
137
137
  [[package]]
138
138
  name = "cc"
139
- version = "1.4.6"
139
+ version = "1.4.7"
140
140
  source = "registry+https://github.com/rust-lang/crates.io-index"
141
- checksum = "a3eb0f42d6c360dc3f8a821f6bf2fdea7f72bfd36b3076eb0e6d1e9e0752fff4"
141
+ checksum = "54413ede23c2daf518f35156dfde027feb2374004d63bd497f983c8db9c0e313"
142
142
  dependencies = [
143
143
  "find-msvc-tools",
144
144
  "jobserver",
@@ -148,9 +148,9 @@ dependencies = [
148
148
 
149
149
  [[package]]
150
150
  name = "cfg-if"
151
- version = "1.0.4"
151
+ version = "1.0.5"
152
152
  source = "registry+https://github.com/rust-lang/crates.io-index"
153
- checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
153
+ checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600"
154
154
 
155
155
  [[package]]
156
156
  name = "cfg_aliases"
@@ -171,7 +171,7 @@ dependencies = [
171
171
 
172
172
  [[package]]
173
173
  name = "chain-gang"
174
- version = "0.11.2"
174
+ version = "0.11.4"
175
175
  dependencies = [
176
176
  "async-lock",
177
177
  "async-trait",
@@ -197,6 +197,7 @@ dependencies = [
197
197
  "sha1",
198
198
  "sha2",
199
199
  "thiserror",
200
+ "tokio",
200
201
  "url",
201
202
  ]
202
203
 
@@ -345,7 +346,7 @@ checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8"
345
346
  dependencies = [
346
347
  "proc-macro2",
347
348
  "quote",
348
- "syn 3.0.5",
349
+ "syn 3.0.6",
349
350
  ]
350
351
 
351
352
  [[package]]
@@ -454,9 +455,9 @@ dependencies = [
454
455
 
455
456
  [[package]]
456
457
  name = "find-msvc-tools"
457
- version = "0.1.12"
458
+ version = "0.1.13"
458
459
  source = "registry+https://github.com/rust-lang/crates.io-index"
459
- checksum = "3e0f1c7c3a72c66fd80abe965175f7523475c0489a87d3ff9d6e8c87d87a9d2d"
460
+ checksum = "ef25905e51abafe4dcea6c15fec58c57b601cdbd0ee53d22ea1d3016c587d39b"
460
461
 
461
462
  [[package]]
462
463
  name = "fnv"
@@ -675,9 +676,9 @@ dependencies = [
675
676
 
676
677
  [[package]]
677
678
  name = "hyper-rustls"
678
- version = "0.27.9"
679
+ version = "0.27.10"
679
680
  source = "registry+https://github.com/rust-lang/crates.io-index"
680
- checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f"
681
+ checksum = "dfa8e654703247911e29c23fbeaa261834bd9bb74efba2f9acddc37bfb127f53"
681
682
  dependencies = [
682
683
  "http",
683
684
  "hyper",
@@ -995,7 +996,7 @@ dependencies = [
995
996
  "proc-macro2",
996
997
  "quote",
997
998
  "rustversion",
998
- "syn 3.0.5",
999
+ "syn 3.0.6",
999
1000
  ]
1000
1001
 
1001
1002
  [[package]]
@@ -1277,9 +1278,9 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
1277
1278
 
1278
1279
  [[package]]
1279
1280
  name = "rand"
1280
- version = "0.10.2"
1281
+ version = "0.10.3"
1281
1282
  source = "registry+https://github.com/rust-lang/crates.io-index"
1282
- checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80"
1283
+ checksum = "65c9fb96cbc91e3478eaae79a69fcd3f1ae4ad052e471fe6732fff548984b4af"
1283
1284
  dependencies = [
1284
1285
  "chacha20",
1285
1286
  "getrandom 0.4.3",
@@ -1593,7 +1594,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
1593
1594
  dependencies = [
1594
1595
  "proc-macro2",
1595
1596
  "quote",
1596
- "syn 3.0.5",
1597
+ "syn 3.0.6",
1597
1598
  ]
1598
1599
 
1599
1600
  [[package]]
@@ -1730,9 +1731,9 @@ dependencies = [
1730
1731
 
1731
1732
  [[package]]
1732
1733
  name = "syn"
1733
- version = "3.0.5"
1734
+ version = "3.0.6"
1734
1735
  source = "registry+https://github.com/rust-lang/crates.io-index"
1735
- checksum = "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9"
1736
+ checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee"
1736
1737
  dependencies = [
1737
1738
  "proc-macro2",
1738
1739
  "quote",
@@ -1756,7 +1757,7 @@ checksum = "901704edd0dfe137f1987838ee4f259e4e063c31371bdb423f7ae38ec6f77f02"
1756
1757
  dependencies = [
1757
1758
  "proc-macro2",
1758
1759
  "quote",
1759
- "syn 3.0.5",
1760
+ "syn 3.0.6",
1760
1761
  ]
1761
1762
 
1762
1763
  [[package]]
@@ -1803,7 +1804,7 @@ checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af"
1803
1804
  dependencies = [
1804
1805
  "proc-macro2",
1805
1806
  "quote",
1806
- "syn 3.0.5",
1807
+ "syn 3.0.6",
1807
1808
  ]
1808
1809
 
1809
1810
  [[package]]
@@ -1833,9 +1834,21 @@ dependencies = [
1833
1834
  "mio",
1834
1835
  "pin-project-lite",
1835
1836
  "socket2",
1837
+ "tokio-macros",
1836
1838
  "windows-sys 0.61.2",
1837
1839
  ]
1838
1840
 
1841
+ [[package]]
1842
+ name = "tokio-macros"
1843
+ version = "2.7.2"
1844
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1845
+ checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e"
1846
+ dependencies = [
1847
+ "proc-macro2",
1848
+ "quote",
1849
+ "syn 3.0.6",
1850
+ ]
1851
+
1839
1852
  [[package]]
1840
1853
  name = "tokio-rustls"
1841
1854
  version = "0.26.5"
@@ -1938,9 +1951,9 @@ checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
1938
1951
 
1939
1952
  [[package]]
1940
1953
  name = "unicode-ident"
1941
- version = "1.0.24"
1954
+ version = "1.0.26"
1942
1955
  source = "registry+https://github.com/rust-lang/crates.io-index"
1943
- checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
1956
+ checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954"
1944
1957
 
1945
1958
  [[package]]
1946
1959
  name = "untrusted"
@@ -2033,7 +2046,7 @@ dependencies = [
2033
2046
  "bumpalo",
2034
2047
  "proc-macro2",
2035
2048
  "quote",
2036
- "syn 3.0.5",
2049
+ "syn 3.0.6",
2037
2050
  "wasm-bindgen-shared",
2038
2051
  ]
2039
2052
 
@@ -2238,7 +2251,7 @@ checksum = "33811428bee40dbceb6d545e95754741d17a6aef9a4849f0fd62e2ba4f412a78"
2238
2251
  dependencies = [
2239
2252
  "proc-macro2",
2240
2253
  "quote",
2241
- "syn 3.0.5",
2254
+ "syn 3.0.6",
2242
2255
  "synstructure",
2243
2256
  ]
2244
2257
 
@@ -2259,7 +2272,7 @@ checksum = "f75b4683f6c7f45248d4d64056a24298c6281e0993356d7d1b4a1a962ef10d4a"
2259
2272
  dependencies = [
2260
2273
  "proc-macro2",
2261
2274
  "quote",
2262
- "syn 3.0.5",
2275
+ "syn 3.0.6",
2263
2276
  "synstructure",
2264
2277
  ]
2265
2278
 
@@ -2299,7 +2312,7 @@ checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da"
2299
2312
  dependencies = [
2300
2313
  "proc-macro2",
2301
2314
  "quote",
2302
- "syn 3.0.5",
2315
+ "syn 3.0.6",
2303
2316
  ]
2304
2317
 
2305
2318
  [[package]]
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "chain-gang"
3
- version = "0.11.2"
3
+ version = "0.11.4"
4
4
  description = "This is a library that enables monitoring of multiple blockchains (BTC, BCH, BSV)."
5
5
  repository = "https://github.com/nchain-innovation/chain-gang"
6
6
  homepage = "https://github.com/nchain-innovation/chain-gang"
@@ -44,6 +44,9 @@ serde_json = { version = "1.0.151" }
44
44
  reqwest = { version = "0.13.4", features = ["json"], optional = true }
45
45
  async-lock = { version = "3.4.2", optional = true }
46
46
  async-trait = { version = "0.1.91", optional = true }
47
+ # Already in the tree via reqwest; the "time" feature is for the backoff
48
+ # between paginated WhatsOnChain requests
49
+ tokio = { version = "1", features = ["time"], optional = true }
47
50
 
48
51
  # For python feature
49
52
  # abi3-py311 builds against the stable ABI: one wheel (cp311-abi3) works on
@@ -52,6 +55,12 @@ async-trait = { version = "0.1.91", optional = true }
52
55
  pyo3 = { version = "0.29.0", optional = true, features = ["abi3-py311"] }
53
56
  regex = "1.13.1"
54
57
 
58
+ # The rate limit added for CS-457 is a timing behaviour, so its tests have to
59
+ # await. The crate's own tokio dependency carries only "time", which is all the
60
+ # library needs; a test runtime is dev-only and reaches no consumer.
61
+ [dev-dependencies]
62
+ tokio = { version = "1", features = ["macros", "rt", "time"] }
63
+
55
64
  [lib]
56
65
  name = "chain_gang"
57
66
  crate-type = ["cdylib", "lib"]
@@ -64,5 +73,5 @@ lto = true # Enable link-time optimizations to shrink binary
64
73
  # serde and serde_json are unconditional dependencies, so there is nothing
65
74
  # left for the default feature to switch on
66
75
  default = []
67
- interface = ["dep:reqwest", "dep:async-lock", "dep:async-trait"]
76
+ interface = ["dep:reqwest", "dep:async-lock", "dep:async-trait", "dep:tokio"]
68
77
  python = ["dep:pyo3"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tx_engine
3
- Version: 0.11.2
3
+ Version: 0.11.4
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: 3
6
6
  Classifier: Programming Language :: Python :: 3.11