Skip to content

Commit

Permalink
Merge bitcoin#26694: test: get_previous_releases.py: M1/M2 macs can…
Browse files Browse the repository at this point in the history
…'t run unsigned arm64 binaries; self-sign when needed

dc12f2e test: improve error msg on previous release tarball extraction failure (kdmukai)
7121fd8 test: self-sign previous release binaries for arm64 macOS (kdmukai)

Pull request description:

  ## The Problem
  If you run `test/get_previous_releases.py -b` on an M1 or M2 mac, you'll get an unsigned v23.0 binary in the arm64 tarball. macOS [sets stricter requirements on ARM binaries](https://news.ycombinator.com/item?id=26996578) so the unsigned arm64 binary is apparently completely unusable without being signed/notarized(?).

  This means that any test that depends on a previous release (e.g. `wallet_backwards_compatibility.py`) will fail because the v23.0 node cannot launch:

  ```
  TestFramework (ERROR): Assertion failed
  Traceback (most recent call last):
    File "/Users/kdmukai/dev/bitcoin-core/test/functional/test_framework/test_framework.py", line 563, in start_nodes
      node.wait_for_rpc_connection()
    File "/Users/kdmukai/dev/bitcoin-core/test/functional/test_framework/test_node.py", line 231, in wait_for_rpc_connection
      raise FailedToStartError(self._node_msg(
  test_framework.test_node.FailedToStartError: [node 2] bitcoind exited with status -9 during initialization
  ```

  This can also be confirmed by downloading bitcoin-23.0-arm64-apple-darwin.tar.gz (https://bitcoincore.org/bin/bitcoin-core-23.0/) and trying to run any of the binaries manually on an M1 or M2 mac.

  ## Solution in this PR
  (UPDATED) Per @ hebasto, we can self-sign the arm64 binaries. This PR checks each binary in the previous release's "bin/" and verifies if the arm64 binary is signed. If not, attempt to self-sign and confirm success.

  (note: an earlier version of this PR downloaded the x86_64 binary as a workaround but this approach has been discarded)

  ## Longer term solution
  If possible, produce signed arm64 binaries in a future v23.x tarball?

  Note that this same problem affects the new v24.0.1 arm64 tarball so perhaps a signed v24.x.x tarball would also be ideal?

  That being said, this PR will check all current and future arm64 binaries and self-sign as needed, so perhaps we need not worry about pre-signing the tarball binaries. And I did test a version of `get_previous_releases.py` that includes the new v24.0.1 binaries and it successfully self-signed both v23.0 and v24.0.1, as expected.

  ## Further info:
  Somewhat related to: bitcoin#15774 (comment)

  And @ fanquake noted on IRC that you can confirm which binaries are or are not signed via:
  ```
  $ codesign -v -d bitcoin-qt
  bitcoin-qt: code object is not signed at all
  ```

ACKs for top commit:
  hebasto:
    ACK dc12f2e

Tree-SHA512: 644895f8e97f5ffb3c4754c1db2c48abd77fa100c2058e3c896af04806596fc2b9c807a3f3a2add5be53301ad40ca2b8171585bd254e691f6eb38714d938396b
  • Loading branch information
MarcoFalke authored and knst committed Nov 20, 2023
1 parent d64e64c commit 0417209
Showing 1 changed file with 30 additions and 1 deletion.
31 changes: 30 additions & 1 deletion test/get_previous_releases.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,39 @@ def download_binary(tag, args) -> int:
ret = subprocess.run(['tar', '-zxf', tarball, '-C', tag,
'--strip-components=1',
'dashcore-{tag}'.format(tag=filename, platform=args.platform)]).returncode
if ret:
if ret != 0:
print(f"Failed to extract the {tag} tarball")
return ret

Path(tarball).unlink()

if tag >= "v19" and platform == "arm64-apple-darwin":
# Starting with v23 there are arm64 binaries for ARM (e.g. M1, M2) macs, but they have to be signed to run
binary_path = f'{os.getcwd()}/{tag}/bin/'

for arm_binary in os.listdir(binary_path):
# Is it already signed?
ret = subprocess.run(
['codesign', '-v', binary_path + arm_binary],
stderr=subprocess.DEVNULL, # Suppress expected stderr output
).returncode
if ret == 1:
# Have to self-sign the binary
ret = subprocess.run(
['codesign', '-s', '-', binary_path + arm_binary]
).returncode
if ret != 0:
print(f"Failed to self-sign {tag} {arm_binary} arm64 binary")
return 1

# Confirm success
ret = subprocess.run(
['codesign', '-v', binary_path + arm_binary]
).returncode
if ret != 0:
print(f"Failed to verify the self-signed {tag} {arm_binary} arm64 binary")
return 1

return 0


Expand Down

0 comments on commit 0417209

Please sign in to comment.