@le-space/rootfs 0.3.18 → 0.3.19
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.
- package/package.json +1 -1
- package/reference/uc-go-peer/rootfs/build-rootfs-image.sh +3 -0
- package/reference/uc-go-peer/rootfs/uc-go-peer-bootstrap-deregister.py +299 -0
- package/reference/uc-go-peer/rootfs/uc-go-peer-bootstrap-deregister.service +19 -0
- package/reference/uc-go-peer/rootfs/uc-go-peer-bootstrap-refresh.py +1 -3
- package/reference/uc-go-peer/rootfs/uc-go-peer-configure.sh +32 -0
package/package.json
CHANGED
|
@@ -86,11 +86,13 @@ virt-customize \
|
|
|
86
86
|
--copy-in "${APP_BINARY}:${GUEST_APP_DIR}" \
|
|
87
87
|
--copy-in "${SCRIPT_DIR}/uc-go-peer-bootstrap.sh:/usr/local/sbin" \
|
|
88
88
|
--copy-in "${SCRIPT_DIR}/uc-go-peer-configure.sh:/usr/local/sbin" \
|
|
89
|
+
--copy-in "${SCRIPT_DIR}/uc-go-peer-bootstrap-deregister.py:/usr/local/sbin" \
|
|
89
90
|
--copy-in "${SCRIPT_DIR}/uc-go-peer-bootstrap-refresh.py:/usr/local/sbin" \
|
|
90
91
|
--copy-in "${SCRIPT_DIR}/uc-go-peer-autotls-refresh.py:/usr/local/sbin" \
|
|
91
92
|
--copy-in "${SCRIPT_DIR}/uc-go-peer-describe.py:/usr/local/sbin" \
|
|
92
93
|
--copy-in "${SCRIPT_DIR}/uc-go-peer-setup-server.py:/usr/local/sbin" \
|
|
93
94
|
--copy-in "${SCRIPT_DIR}/uc-go-peer-bootstrap.service:/etc/systemd/system" \
|
|
95
|
+
--copy-in "${SCRIPT_DIR}/uc-go-peer-bootstrap-deregister.service:/etc/systemd/system" \
|
|
94
96
|
--copy-in "${SCRIPT_DIR}/uc-go-peer-bootstrap-refresh.service:/etc/systemd/system" \
|
|
95
97
|
--copy-in "${SCRIPT_DIR}/uc-go-peer-bootstrap-refresh.timer:/etc/systemd/system" \
|
|
96
98
|
--copy-in "${SCRIPT_DIR}/uc-go-peer-autotls-refresh.service:/etc/systemd/system" \
|
|
@@ -98,6 +100,7 @@ virt-customize \
|
|
|
98
100
|
--run-command "chmod 0755 ${ROOTFS_CONTRACT_BINARY_PATH}" \
|
|
99
101
|
--run-command "chmod 0755 /usr/local/sbin/uc-go-peer-bootstrap.sh" \
|
|
100
102
|
--run-command "chmod 0755 /usr/local/sbin/uc-go-peer-configure.sh" \
|
|
103
|
+
--run-command "chmod 0755 /usr/local/sbin/uc-go-peer-bootstrap-deregister.py" \
|
|
101
104
|
--run-command "chmod 0755 /usr/local/sbin/uc-go-peer-bootstrap-refresh.py" \
|
|
102
105
|
--run-command "chmod 0755 /usr/local/sbin/uc-go-peer-autotls-refresh.py" \
|
|
103
106
|
--run-command "chmod 0755 /usr/local/sbin/uc-go-peer-describe.py" \
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import hashlib
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import subprocess
|
|
6
|
+
import sys
|
|
7
|
+
import time
|
|
8
|
+
import urllib.error
|
|
9
|
+
import urllib.parse
|
|
10
|
+
import urllib.request
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
from eth_account import Account
|
|
14
|
+
from eth_account.messages import encode_defunct
|
|
15
|
+
except ImportError as error: # pragma: no cover - runtime dependency
|
|
16
|
+
raise SystemExit(
|
|
17
|
+
"eth-account is required for guest-side bootstrap deregistration"
|
|
18
|
+
) from error
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
ENV_FILE = os.environ.get("ENV_FILE", "/etc/default/uc-go-peer")
|
|
22
|
+
DESCRIBE_SCRIPT = os.environ.get("DESCRIBE_SCRIPT", "/usr/local/sbin/uc-go-peer-describe.py")
|
|
23
|
+
DEFAULT_API_HOST = os.environ.get("ALEPH_BOOTSTRAP_API_HOST", "https://api2.aleph.im")
|
|
24
|
+
DEFAULT_CHANNEL = os.environ.get("ALEPH_BOOTSTRAP_CHANNEL", "simple-todo")
|
|
25
|
+
DEFAULT_REF = os.environ.get("ALEPH_BOOTSTRAP_REF", "simple-todo-bootstrap")
|
|
26
|
+
DEFAULT_POST_TYPE = os.environ.get("ALEPH_BOOTSTRAP_POST_TYPE", "relay-bootstrap")
|
|
27
|
+
MAX_PREVIOUS_PAGES = int(os.environ.get("ALEPH_BOOTSTRAP_MAX_PREVIOUS_PAGES", "5"))
|
|
28
|
+
PAGINATION = int(os.environ.get("ALEPH_BOOTSTRAP_PAGINATION", "50"))
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def parse_env_file(path: str) -> dict[str, str]:
|
|
32
|
+
values: dict[str, str] = {}
|
|
33
|
+
if not os.path.exists(path):
|
|
34
|
+
return values
|
|
35
|
+
|
|
36
|
+
with open(path, encoding="utf-8") as handle:
|
|
37
|
+
for line in handle:
|
|
38
|
+
stripped = line.strip()
|
|
39
|
+
if not stripped or stripped.startswith("#") or "=" not in stripped:
|
|
40
|
+
continue
|
|
41
|
+
key, value = stripped.split("=", 1)
|
|
42
|
+
values[key.strip()] = value.strip()
|
|
43
|
+
return values
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def json_dumps(payload: object) -> str:
|
|
47
|
+
return json.dumps(payload, separators=(",", ":"))
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def dedupe(values: list[str]) -> list[str]:
|
|
51
|
+
seen: set[str] = set()
|
|
52
|
+
result: list[str] = []
|
|
53
|
+
for value in values:
|
|
54
|
+
if value and value not in seen:
|
|
55
|
+
seen.add(value)
|
|
56
|
+
result.append(value)
|
|
57
|
+
return result
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def sign_personal_message(private_key: str, payload: str) -> str:
|
|
61
|
+
message = encode_defunct(text=payload)
|
|
62
|
+
signed = Account.sign_message(message, private_key=private_key)
|
|
63
|
+
return signed.signature.hex()
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def address_from_private_key(private_key: str) -> str:
|
|
67
|
+
return Account.from_key(private_key).address
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def signature_payload(chain: str, sender: str, message_type: str, item_hash: str) -> str:
|
|
71
|
+
return "\n".join([chain, sender, message_type, item_hash])
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def post_json(url: str, body: dict[str, object]) -> tuple[int, dict]:
|
|
75
|
+
data = json_dumps(body).encode("utf-8")
|
|
76
|
+
request = urllib.request.Request(
|
|
77
|
+
url,
|
|
78
|
+
data=data,
|
|
79
|
+
headers={"content-type": "application/json"},
|
|
80
|
+
method="POST",
|
|
81
|
+
)
|
|
82
|
+
try:
|
|
83
|
+
with urllib.request.urlopen(request, timeout=30) as response:
|
|
84
|
+
payload = response.read().decode("utf-8")
|
|
85
|
+
return response.status, json.loads(payload or "{}")
|
|
86
|
+
except urllib.error.HTTPError as error:
|
|
87
|
+
payload = error.read().decode("utf-8")
|
|
88
|
+
try:
|
|
89
|
+
return error.code, json.loads(payload or "{}")
|
|
90
|
+
except json.JSONDecodeError:
|
|
91
|
+
return error.code, {"details": payload}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def get_json(url: str) -> dict:
|
|
95
|
+
with urllib.request.urlopen(url, timeout=30) as response:
|
|
96
|
+
return json.loads(response.read().decode("utf-8") or "{}")
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def sign_aleph_message(unsigned_message: dict[str, object], private_key: str) -> dict[str, object]:
|
|
100
|
+
signed = dict(unsigned_message)
|
|
101
|
+
signed["signature"] = sign_personal_message(
|
|
102
|
+
private_key,
|
|
103
|
+
signature_payload(
|
|
104
|
+
str(unsigned_message["chain"]),
|
|
105
|
+
str(unsigned_message["sender"]),
|
|
106
|
+
str(unsigned_message["type"]),
|
|
107
|
+
str(unsigned_message["item_hash"]),
|
|
108
|
+
),
|
|
109
|
+
)
|
|
110
|
+
return signed
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def broadcast_aleph_message(api_host: str, message: dict[str, object]) -> tuple[int, dict]:
|
|
114
|
+
url = urllib.parse.urljoin(api_host.rstrip("/") + "/", "api/v0/messages")
|
|
115
|
+
attempts = [
|
|
116
|
+
{"sync": True, "message": message},
|
|
117
|
+
{**message, "sync": True},
|
|
118
|
+
dict(message),
|
|
119
|
+
]
|
|
120
|
+
last: tuple[int, dict] | None = None
|
|
121
|
+
for attempt in attempts:
|
|
122
|
+
last = post_json(url, attempt)
|
|
123
|
+
if 200 <= last[0] < 300:
|
|
124
|
+
return last
|
|
125
|
+
if last is None:
|
|
126
|
+
raise RuntimeError("Aleph broadcast failed before any attempt was made")
|
|
127
|
+
raise RuntimeError(f"Aleph broadcast failed: {last[0]} {json_dumps(last[1])}")
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def parse_post_record(entry: object) -> dict[str, object] | None:
|
|
131
|
+
if not isinstance(entry, dict):
|
|
132
|
+
return None
|
|
133
|
+
item_hash = entry.get("item_hash") or entry.get("hash")
|
|
134
|
+
if not isinstance(item_hash, str) or not item_hash:
|
|
135
|
+
return None
|
|
136
|
+
|
|
137
|
+
sender = entry.get("address") or entry.get("sender")
|
|
138
|
+
item_content = entry.get("item_content")
|
|
139
|
+
if isinstance(item_content, str):
|
|
140
|
+
try:
|
|
141
|
+
item_content = json.loads(item_content)
|
|
142
|
+
except json.JSONDecodeError:
|
|
143
|
+
item_content = None
|
|
144
|
+
|
|
145
|
+
if not isinstance(item_content, dict):
|
|
146
|
+
return None
|
|
147
|
+
|
|
148
|
+
content = item_content.get("content")
|
|
149
|
+
if not isinstance(content, dict):
|
|
150
|
+
return None
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
"item_hash": item_hash,
|
|
154
|
+
"sender": sender,
|
|
155
|
+
"registration_id": content.get("registrationId"),
|
|
156
|
+
"peer_id": content.get("peerId"),
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def load_peer_id() -> str | None:
|
|
161
|
+
describe = subprocess.run([DESCRIBE_SCRIPT], check=False, capture_output=True, text=True)
|
|
162
|
+
if describe.returncode != 0:
|
|
163
|
+
return None
|
|
164
|
+
try:
|
|
165
|
+
metadata = json.loads(describe.stdout.strip() or "{}")
|
|
166
|
+
except json.JSONDecodeError:
|
|
167
|
+
return None
|
|
168
|
+
peer_id = metadata.get("peer_id")
|
|
169
|
+
if isinstance(peer_id, str) and peer_id.strip():
|
|
170
|
+
return peer_id.strip()
|
|
171
|
+
return None
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def fetch_current_hashes(
|
|
175
|
+
api_host: str,
|
|
176
|
+
channel: str,
|
|
177
|
+
ref: str,
|
|
178
|
+
post_type: str,
|
|
179
|
+
sender: str,
|
|
180
|
+
registration_id: str | None,
|
|
181
|
+
peer_id: str | None,
|
|
182
|
+
) -> list[str]:
|
|
183
|
+
found: list[str] = []
|
|
184
|
+
for page in range(1, MAX_PREVIOUS_PAGES + 1):
|
|
185
|
+
url = (
|
|
186
|
+
f"{api_host.rstrip('/')}/api/v0/posts.json?"
|
|
187
|
+
f"channels={urllib.parse.quote(channel)}&"
|
|
188
|
+
f"refs={urllib.parse.quote(ref)}&"
|
|
189
|
+
f"types={urllib.parse.quote(post_type)}&"
|
|
190
|
+
f"pagination={PAGINATION}&page={page}"
|
|
191
|
+
)
|
|
192
|
+
payload = get_json(url)
|
|
193
|
+
posts = payload.get("posts")
|
|
194
|
+
if not isinstance(posts, list):
|
|
195
|
+
break
|
|
196
|
+
|
|
197
|
+
for entry in posts:
|
|
198
|
+
parsed = parse_post_record(entry)
|
|
199
|
+
if parsed is None:
|
|
200
|
+
continue
|
|
201
|
+
if str(parsed["sender"]).lower() != sender.lower():
|
|
202
|
+
continue
|
|
203
|
+
if registration_id and parsed["registration_id"] == registration_id:
|
|
204
|
+
found.append(str(parsed["item_hash"]))
|
|
205
|
+
continue
|
|
206
|
+
if peer_id and parsed["peer_id"] == peer_id:
|
|
207
|
+
found.append(str(parsed["item_hash"]))
|
|
208
|
+
|
|
209
|
+
if len(posts) < PAGINATION:
|
|
210
|
+
break
|
|
211
|
+
|
|
212
|
+
return dedupe(found)
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def broadcast_forget(
|
|
216
|
+
api_host: str,
|
|
217
|
+
sender: str,
|
|
218
|
+
private_key: str,
|
|
219
|
+
hashes: list[str],
|
|
220
|
+
channel: str,
|
|
221
|
+
) -> tuple[int, dict] | None:
|
|
222
|
+
if not hashes:
|
|
223
|
+
return None
|
|
224
|
+
|
|
225
|
+
now_seconds = time.time()
|
|
226
|
+
item_content = json_dumps(
|
|
227
|
+
{
|
|
228
|
+
"address": sender,
|
|
229
|
+
"time": now_seconds,
|
|
230
|
+
"hashes": hashes,
|
|
231
|
+
"aggregates": [],
|
|
232
|
+
"reason": f"Deregister relay bootstrap records for {sender}",
|
|
233
|
+
}
|
|
234
|
+
)
|
|
235
|
+
unsigned = {
|
|
236
|
+
"sender": sender,
|
|
237
|
+
"chain": "ETH",
|
|
238
|
+
"type": "FORGET",
|
|
239
|
+
"item_hash": hashlib.sha256(item_content.encode("utf-8")).hexdigest(),
|
|
240
|
+
"item_type": "inline",
|
|
241
|
+
"item_content": item_content,
|
|
242
|
+
"time": now_seconds,
|
|
243
|
+
"channel": channel,
|
|
244
|
+
}
|
|
245
|
+
return broadcast_aleph_message(api_host, sign_aleph_message(unsigned, private_key))
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
def main() -> None:
|
|
249
|
+
env_values = parse_env_file(ENV_FILE)
|
|
250
|
+
publisher_private_key = env_values.get("ALEPH_BOOTSTRAP_PUBLISHER_PRIVATE_KEY", "").strip()
|
|
251
|
+
registration_id = env_values.get("ALEPH_BOOTSTRAP_REGISTRATION_ID", "").strip() or None
|
|
252
|
+
if not publisher_private_key:
|
|
253
|
+
print(json_dumps({"status": "skipped", "reason": "missing publisher key"}))
|
|
254
|
+
return
|
|
255
|
+
|
|
256
|
+
publisher_address = address_from_private_key(publisher_private_key)
|
|
257
|
+
peer_id = load_peer_id()
|
|
258
|
+
channel = env_values.get("ALEPH_BOOTSTRAP_CHANNEL", DEFAULT_CHANNEL).strip() or DEFAULT_CHANNEL
|
|
259
|
+
ref = env_values.get("ALEPH_BOOTSTRAP_REF", DEFAULT_REF).strip() or DEFAULT_REF
|
|
260
|
+
post_type = env_values.get("ALEPH_BOOTSTRAP_POST_TYPE", DEFAULT_POST_TYPE).strip() or DEFAULT_POST_TYPE
|
|
261
|
+
api_host = env_values.get("ALEPH_BOOTSTRAP_API_HOST", DEFAULT_API_HOST).strip() or DEFAULT_API_HOST
|
|
262
|
+
|
|
263
|
+
hashes = fetch_current_hashes(
|
|
264
|
+
api_host,
|
|
265
|
+
channel,
|
|
266
|
+
ref,
|
|
267
|
+
post_type,
|
|
268
|
+
publisher_address,
|
|
269
|
+
registration_id,
|
|
270
|
+
peer_id,
|
|
271
|
+
)
|
|
272
|
+
if not hashes:
|
|
273
|
+
print(json_dumps({"status": "skipped", "reason": "no matching bootstrap records"}))
|
|
274
|
+
return
|
|
275
|
+
|
|
276
|
+
http_status, response = broadcast_forget(
|
|
277
|
+
api_host, publisher_address, publisher_private_key, hashes, channel
|
|
278
|
+
) or (0, {})
|
|
279
|
+
print(
|
|
280
|
+
json_dumps(
|
|
281
|
+
{
|
|
282
|
+
"status": "forgotten",
|
|
283
|
+
"httpStatus": http_status,
|
|
284
|
+
"sender": publisher_address,
|
|
285
|
+
"registrationId": registration_id,
|
|
286
|
+
"peerId": peer_id,
|
|
287
|
+
"forgottenHashes": hashes,
|
|
288
|
+
"response": response,
|
|
289
|
+
}
|
|
290
|
+
)
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
if __name__ == "__main__":
|
|
295
|
+
try:
|
|
296
|
+
main()
|
|
297
|
+
except Exception as error: # pragma: no cover - runtime error path
|
|
298
|
+
print(json_dumps({"status": "error", "error": str(error)}), file=sys.stderr)
|
|
299
|
+
raise
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
[Unit]
|
|
2
|
+
Description=Best-effort Aleph bootstrap deregistration on shutdown for uc-go-peer
|
|
3
|
+
After=network-online.target
|
|
4
|
+
Wants=network-online.target
|
|
5
|
+
ConditionPathExists=/etc/default/uc-go-peer.ready
|
|
6
|
+
|
|
7
|
+
[Service]
|
|
8
|
+
Type=oneshot
|
|
9
|
+
RemainAfterExit=yes
|
|
10
|
+
Environment=ENV_FILE=/etc/default/uc-go-peer
|
|
11
|
+
Environment=DESCRIBE_SCRIPT=/usr/local/sbin/uc-go-peer-describe.py
|
|
12
|
+
ExecStart=/bin/true
|
|
13
|
+
ExecStop=/usr/bin/python3 /usr/local/sbin/uc-go-peer-bootstrap-deregister.py
|
|
14
|
+
StandardOutput=journal
|
|
15
|
+
StandardError=journal
|
|
16
|
+
TimeoutStopSec=25
|
|
17
|
+
|
|
18
|
+
[Install]
|
|
19
|
+
WantedBy=multi-user.target
|
|
@@ -466,9 +466,6 @@ def main() -> None:
|
|
|
466
466
|
version,
|
|
467
467
|
now_ms,
|
|
468
468
|
)
|
|
469
|
-
if owner_authorization is None:
|
|
470
|
-
print(json_dumps({"status": "skipped", "reason": "missing owner authorization"}))
|
|
471
|
-
return
|
|
472
469
|
|
|
473
470
|
proof_payload = relay_proof_payload(
|
|
474
471
|
peer_id,
|
|
@@ -529,6 +526,7 @@ def main() -> None:
|
|
|
529
526
|
"publishedMultiaddrs": multiaddrs,
|
|
530
527
|
"publishedBrowserMultiaddrs": browser_multiaddrs,
|
|
531
528
|
"forgottenHashes": previous_hashes,
|
|
529
|
+
"ownerAuthorizationPresent": owner_authorization is not None,
|
|
532
530
|
"forgetResponse": forget_response[1] if forget_response else None,
|
|
533
531
|
"response": response,
|
|
534
532
|
}
|
|
@@ -11,6 +11,7 @@ SERVICE_NAME="${SERVICE_NAME:-uc-go-peer.service}"
|
|
|
11
11
|
AUTOTLS_REFRESH_SERVICE="${AUTOTLS_REFRESH_SERVICE:-uc-go-peer-autotls-refresh.service}"
|
|
12
12
|
BOOTSTRAP_REFRESH_TIMER="${BOOTSTRAP_REFRESH_TIMER:-uc-go-peer-bootstrap-refresh.timer}"
|
|
13
13
|
BOOTSTRAP_REFRESH_SERVICE="${BOOTSTRAP_REFRESH_SERVICE:-uc-go-peer-bootstrap-refresh.service}"
|
|
14
|
+
BOOTSTRAP_DEREGISTER_SERVICE="${BOOTSTRAP_DEREGISTER_SERVICE:-uc-go-peer-bootstrap-deregister.service}"
|
|
14
15
|
CADDY_SERVICE="${CADDY_SERVICE:-caddy.service}"
|
|
15
16
|
CADDYFILE="${CADDYFILE:-/etc/caddy/Caddyfile}"
|
|
16
17
|
BOOTSTRAP_SERVICE="${BOOTSTRAP_SERVICE:-uc-go-peer-bootstrap.service}"
|
|
@@ -97,6 +98,27 @@ current_identity_path() {
|
|
|
97
98
|
printf '/var/lib/uc-go-peer/identity.key\n'
|
|
98
99
|
}
|
|
99
100
|
|
|
101
|
+
current_bootstrap_publisher_private_key() {
|
|
102
|
+
local existing
|
|
103
|
+
existing="$(grep -E '^[#[:space:]]*ALEPH_BOOTSTRAP_PUBLISHER_PRIVATE_KEY=' "${ENV_FILE}" 2>/dev/null | tail -n1 | cut -d= -f2- || true)"
|
|
104
|
+
if [ -n "${existing}" ]; then
|
|
105
|
+
printf '%s\n' "${existing}"
|
|
106
|
+
return
|
|
107
|
+
fi
|
|
108
|
+
printf '\n'
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
generate_bootstrap_publisher_private_key() {
|
|
112
|
+
while true; do
|
|
113
|
+
local candidate
|
|
114
|
+
candidate="$(openssl rand -hex 32)"
|
|
115
|
+
if [ -n "${candidate}" ] && [ "${candidate}" != "0000000000000000000000000000000000000000000000000000000000000000" ]; then
|
|
116
|
+
printf '0x%s\n' "${candidate}"
|
|
117
|
+
return
|
|
118
|
+
fi
|
|
119
|
+
done
|
|
120
|
+
}
|
|
121
|
+
|
|
100
122
|
while [ "$#" -gt 0 ]; do
|
|
101
123
|
case "$1" in
|
|
102
124
|
--public-ipv4)
|
|
@@ -179,6 +201,13 @@ fi
|
|
|
179
201
|
touch "${ENV_FILE}"
|
|
180
202
|
rm -f "${AUTOTLS_READY_FILE}" "${AUTOTLS_ZONE_FILE}" "${AUTOTLS_HOSTS_FILE}" "${AUTOTLS_CADDY_READY_FILE}"
|
|
181
203
|
|
|
204
|
+
if [ -z "${BOOTSTRAP_PUBLISHER_PRIVATE_KEY}" ]; then
|
|
205
|
+
BOOTSTRAP_PUBLISHER_PRIVATE_KEY="$(current_bootstrap_publisher_private_key)"
|
|
206
|
+
fi
|
|
207
|
+
if [ -z "${BOOTSTRAP_PUBLISHER_PRIVATE_KEY}" ]; then
|
|
208
|
+
BOOTSTRAP_PUBLISHER_PRIVATE_KEY="$(generate_bootstrap_publisher_private_key)"
|
|
209
|
+
fi
|
|
210
|
+
|
|
182
211
|
announce=(
|
|
183
212
|
"/ip4/${PUBLIC_IPV4}/tcp/${TCP_PORT}"
|
|
184
213
|
)
|
|
@@ -234,6 +263,7 @@ if [ -n "${UDP_PORT}" ]; then
|
|
|
234
263
|
fi
|
|
235
264
|
if [ -n "${BOOTSTRAP_PUBLISHER_PRIVATE_KEY}" ]; then
|
|
236
265
|
write_env_var "ALEPH_BOOTSTRAP_PUBLISHER_PRIVATE_KEY" "${BOOTSTRAP_PUBLISHER_PRIVATE_KEY}"
|
|
266
|
+
write_env_var "GO_PEER_IDENTITY_EVM_PRIVATE_KEY" "${BOOTSTRAP_PUBLISHER_PRIVATE_KEY}"
|
|
237
267
|
fi
|
|
238
268
|
if [ -n "${BOOTSTRAP_PUBLISHER_LIBP2P_IDENTITY_B64}" ]; then
|
|
239
269
|
identity_path="$(current_identity_path)"
|
|
@@ -261,6 +291,8 @@ if [ "${START_SERVICE}" -eq 1 ]; then
|
|
|
261
291
|
systemctl restart "${SERVICE_NAME}"
|
|
262
292
|
systemctl enable "${AUTOTLS_REFRESH_SERVICE}"
|
|
263
293
|
systemctl enable "${BOOTSTRAP_REFRESH_TIMER}"
|
|
294
|
+
systemctl enable "${BOOTSTRAP_DEREGISTER_SERVICE}"
|
|
295
|
+
systemctl restart "${BOOTSTRAP_DEREGISTER_SERVICE}"
|
|
264
296
|
systemctl start "${BOOTSTRAP_REFRESH_TIMER}"
|
|
265
297
|
systemctl restart --no-block "${BOOTSTRAP_REFRESH_SERVICE}" || true
|
|
266
298
|
if [ -n "${PROXY_HOSTNAME}" ]; then
|