diff --git a/charts/tezos-proto-cruncher/README.md b/charts/tezos-proto-cruncher/README.md index ab7622301..f119c8b00 100644 --- a/charts/tezos-proto-cruncher/README.md +++ b/charts/tezos-proto-cruncher/README.md @@ -3,4 +3,12 @@ This chart deploys a daemonset to perform a brute-force search of a vanity protocol name. +It leverages this project: + +https://github.com/oxheadalpha/tz-proto-vanity + +It runs in a daemonset and uploads matches to a bucket. + +Thus you can run arbitrarily large k8s clusters for this purpose and the daemon will utilize all nodes to their full potential. + See values.yaml for details. diff --git a/charts/tezos-proto-cruncher/scripts/proto-cruncher.py b/charts/tezos-proto-cruncher/scripts/proto-cruncher.py deleted file mode 100644 index f826868f3..000000000 --- a/charts/tezos-proto-cruncher/scripts/proto-cruncher.py +++ /dev/null @@ -1,79 +0,0 @@ -import hashlib -import random -import base58 -import string -import os -import sys -import re - - -proto_file = sys.argv[1] - - -def tb(l): - return b"".join(map(lambda x: x.to_bytes(1, "big"), l)) - - -proto_prefix = tb([2, 170]) - -PROTO_NAME = os.getenv("PROTO_NAME") -VANITY_STRING = os.getenv("VANITY_STRING") -NUM_NONCE_DIGITS = int(os.getenv("NUM_NONCE_DIGITS", 16)) -BUCKET_NAME = os.getenv("BUCKET_NAME") -BUCKET_ENDPOINT_URL = os.getenv("BUCKET_ENDPOINT_URL") -BUCKET_REGION = os.getenv("BUCKET_REGION") - -if not VANITY_STRING: - raise ValueError("VANITY_STRING env var must be set") - -if BUCKET_NAME: - import boto3 - - s3 = boto3.resource( - "s3", region_name=BUCKET_REGION, endpoint_url=f"https://{BUCKET_ENDPOINT_URL}" - ) - -with open(proto_file, "rb") as f: - proto_bytes = f.read() - -with open(proto_file, "rb") as f: - proto_lines = f.readlines() - - -# For speed, we precompute the hash of the proto without the last line -# containing the vanity nonce. -# Later on, we add the last line and recompute. -# This speeds up the brute force by a large factor, compared to hashing -# in full at every try. -original_nonce = proto_lines[-1] -# First 4 bytes are truncated (not used in proto hashing) -proto_hash = hashlib.blake2b(proto_bytes[4:][: -len(original_nonce)], digest_size=32) - - -def get_hash(vanity_nonce, proto_hash): - proto_hash.update(vanity_nonce) - return base58.b58encode_check(proto_prefix + proto_hash.digest()).decode("utf-8") - - -print( - f"Original proto nonce: {original_nonce} and hash: {get_hash(original_nonce, proto_hash.copy())}" -) - -while True: - # Warning - assuming the nonce is 16 chars in the original proto. - # If it is not, make sure to set NUM_NONCE_DIGITS to the right number - # otherwise you will get bad nonces. - new_nonce_digits = "".join( - random.choice(string.digits) for _ in range(NUM_NONCE_DIGITS) - ) - new_nonce = b"(* Vanity nonce: " + bytes(new_nonce_digits, "utf-8") + b" *)\n" - - new_hash = get_hash(new_nonce, proto_hash.copy()) - if re.match(f"^{VANITY_STRING}.*", new_hash): - print(f"Found vanity nonce: {new_nonce} and hash: {new_hash}") - if BUCKET_NAME: - try: - s3.Object(BUCKET_NAME, f"{PROTO_NAME}_{new_hash}").put(Body=new_nonce) - except: - print("ERROR: upload of the nonce and hash to s3 failed.") - continue diff --git a/charts/tezos-proto-cruncher/scripts/proto-downloader.py b/charts/tezos-proto-cruncher/scripts/tezos-proto-cruncher.py similarity index 53% rename from charts/tezos-proto-cruncher/scripts/proto-downloader.py rename to charts/tezos-proto-cruncher/scripts/tezos-proto-cruncher.py index 6f9a07467..65c544d59 100644 --- a/charts/tezos-proto-cruncher/scripts/proto-downloader.py +++ b/charts/tezos-proto-cruncher/scripts/tezos-proto-cruncher.py @@ -1,24 +1,33 @@ +import boto3 import os +import subprocess +import sys BUCKET_NAME = os.environ["BUCKET_NAME"] BUCKET_ENDPOINT_URL = os.environ["BUCKET_ENDPOINT_URL"] BUCKET_REGION = os.environ["BUCKET_REGION"] PROTO_NAME = os.environ["PROTO_NAME"] - -import boto3 +VANITY_STRING = os.environ["VANITY_STRING"] s3 = boto3.resource( "s3", region_name=BUCKET_REGION, endpoint_url=f"https://{BUCKET_ENDPOINT_URL}" ) print(f"Downloading {PROTO_NAME}") -proto_file = f"/{PROTO_NAME}" +proto_file = f"/opt/{PROTO_NAME}" s3_bucket = s3.Bucket(BUCKET_NAME) try: s3_bucket.download_file(PROTO_NAME, proto_file) except botocore.exceptions.ClientError as e: if e.response["Error"]["Code"] == "404": print("The object does not exist.") + sys.exit(1) else: raise +cmd = subprocess.Popen(['/opt/tz-proto-vanity', f'/opt/{PROTO_NAME}', VANITY_STRING, '-f', 'csv'], stdout=subprocess.PIPE) +next(cmd.stdout) # ignore first line of csv +for line in cmd.stdout: + linesplit = line.decode("utf-8").split(",") + print(f"found vanity hash {linesplit[0]} with nonce {linesplit[1]}") + s3.Object(BUCKET_NAME, f"{PROTO_NAME}_{linesplit[0]}").put(Body=linesplit[1]) diff --git a/charts/tezos-proto-cruncher/scripts/tezos-proto-cruncher.sh b/charts/tezos-proto-cruncher/scripts/tezos-proto-cruncher.sh index 093a5839d..8344bf420 100644 --- a/charts/tezos-proto-cruncher/scripts/tezos-proto-cruncher.sh +++ b/charts/tezos-proto-cruncher/scripts/tezos-proto-cruncher.sh @@ -1,11 +1,6 @@ set -eo pipefail -apk add parallel +apk add py3-pip pip install boto3 -python /proto-downloader.py - -if [ -z "${NUM_PARALLEL_PROCESSES}" ]; then - # Launch one process per CPU core to maximize utilization - NUM_PARALLEL_PROCESSES=$(grep -c ^processor /proc/cpuinfo) -fi -seq $NUM_PARALLEL_PROCESSES | parallel --ungroup python /proto-cruncher.py /${PROTO_NAME} +export PYTHONUNBUFFERED=1 +python /tezos-proto-cruncher.py diff --git a/charts/tezos-proto-cruncher/templates/config.yaml b/charts/tezos-proto-cruncher/templates/config.yaml index ea76421c0..cd7eec27d 100644 --- a/charts/tezos-proto-cruncher/templates/config.yaml +++ b/charts/tezos-proto-cruncher/templates/config.yaml @@ -24,7 +24,5 @@ apiVersion: v1 metadata: name: scripts data: - proto-cruncher.py: | -{{ tpl ($.Files.Get (print "scripts/proto-cruncher.py")) $ | indent 4 }} - proto-downloader.py: | -{{ tpl ($.Files.Get (print "scripts/proto-downloader.py")) $ | indent 4 }} + tezos-proto-cruncher.py: | +{{ tpl ($.Files.Get (print "scripts/tezos-proto-cruncher.py")) $ | indent 4 }} diff --git a/charts/tezos-proto-cruncher/templates/daemonset.yaml b/charts/tezos-proto-cruncher/templates/daemonset.yaml index d5c86fb32..08c1a0592 100644 --- a/charts/tezos-proto-cruncher/templates/daemonset.yaml +++ b/charts/tezos-proto-cruncher/templates/daemonset.yaml @@ -27,14 +27,11 @@ spec: - name: {{ .Chart.Name }} securityContext: {{- toYaml .Values.securityContext | nindent 12 }} - image: "{{ .Values.tezos_k8s_images.utils }}" + image: "{{ .Values.images.tz_proto_vanity }}" volumeMounts: - - mountPath: /proto-cruncher.py + - mountPath: /tezos-proto-cruncher.py name: scripts - subPath: proto-cruncher.py - - mountPath: /proto-downloader.py - name: scripts - subPath: proto-downloader.py + subPath: tezos-proto-cruncher.py envFrom: - secretRef: name: s3-secrets diff --git a/charts/tezos-proto-cruncher/values.yaml b/charts/tezos-proto-cruncher/values.yaml index 9f3bf4850..614a32128 100644 --- a/charts/tezos-proto-cruncher/values.yaml +++ b/charts/tezos-proto-cruncher/values.yaml @@ -1,3 +1,5 @@ +images: + tz_proto_vanity: ghcr.io/oxheadalpha/tz-proto-vanity:latest # tezos-proto-cruncher downloads a protocol in binary format # from a S3 bucket, and writes the results in the same bucket. # Put the credentials for access to your bucket below.