Skip to content

Commit 255e39c

Browse files
scripts: copy prod scripts from 0.14.1 to 0.14.0 (#9763)
1 parent 75f8696 commit 255e39c

File tree

4 files changed

+1094
-0
lines changed

4 files changed

+1094
-0
lines changed
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
#!/usr/bin/env python3
2+
3+
from typing import Optional
4+
5+
import urllib.error
6+
import urllib.parse
7+
import urllib.request
8+
from update_config_and_restart_nodes_lib import (
9+
ApolloArgsParserBuilder,
10+
RestartStrategy,
11+
Service,
12+
get_configmap,
13+
get_context_list_from_args,
14+
get_current_block_number,
15+
get_logs_explorer_url,
16+
get_namespace_list_from_args,
17+
parse_config_from_yaml,
18+
print_colored,
19+
update_config_and_restart_nodes,
20+
)
21+
22+
23+
# TODO(guy.f): Remove this once we have metrics we use to decide based on.
24+
def get_logs_explorer_url_for_proposal(
25+
namespace: str,
26+
validator_id: str,
27+
min_block_number: int,
28+
project_name: str,
29+
) -> str:
30+
# Remove the 0x prefix from the validator id to get the number.
31+
validator_id = validator_id[2:]
32+
33+
query = (
34+
f'resource.labels.namespace_name:"{urllib.parse.quote(namespace)}"\n'
35+
f'resource.labels.container_name="sequencer-core"\n'
36+
f'textPayload =~ "DECISION_REACHED:.*proposer 0x0*{validator_id}"\n'
37+
f'CAST(REGEXP_EXTRACT(textPayload, "height: (\\\\d+)"), "INT64") > {min_block_number}'
38+
)
39+
return get_logs_explorer_url(query, project_name)
40+
41+
42+
def get_validator_id(namespace: str, context: Optional[str]) -> str:
43+
# Get current config and normalize it (e.g. " vs ') to ensure not showing bogus diffs.
44+
original_config = get_configmap(namespace, context, Service.Core)
45+
_, config_data = parse_config_from_yaml(original_config)
46+
47+
return config_data["validator_id"]
48+
49+
50+
def main():
51+
usage_example = """
52+
Examples:
53+
# Restart all nodes at once.
54+
%(prog)s --namespace-prefix apollo-sepolia-integration --num-nodes 3 --feeder-url feeder.integration-sepolia.starknet.io --project-name my-gcp-project
55+
%(prog)s -n apollo-sepolia-integration -m 3 -f feeder.integration-sepolia.starknet.io --project-name my-gcp-project
56+
57+
# Restart nodes with cluster prefix
58+
%(prog)s -n apollo-sepolia-integration -m 3 -c my-cluster -f feeder.integration-sepolia.starknet.io --project-name my-gcp-project
59+
60+
# Restart nodes starting from specific node index
61+
%(prog)s -n apollo-sepolia-integration -m 3 -s 5 -f feeder.integration-sepolia.starknet.io --project-name my-gcp-project
62+
63+
# Use different feeder URL
64+
%(prog)s -n apollo-sepolia-integration -m 3 -f feeder.integration-sepolia.starknet.io --project-name my-gcp-project
65+
66+
# Use namespace list instead of prefix (restart specific namespaces)
67+
%(prog)s --namespace-list apollo-sepolia-integration-0 apollo-sepolia-integration-2 -f feeder.integration-sepolia.starknet.io --project-name my-gcp-project
68+
%(prog)s -N apollo-sepolia-integration-0 apollo-sepolia-integration-2 -f feeder.integration-sepolia.starknet.io --project-name my-gcp-project
69+
70+
# Use cluster list for multiple clusters (only works with namespace-list, not namespace-prefix)
71+
%(prog)s -N apollo-sepolia-integration-0 apollo-sepolia-integration-1 -C cluster1 cluster2 -f feeder.integration-sepolia.starknet.io --project-name my-gcp-project
72+
%(prog)s --namespace-list apollo-sepolia-integration-0 apollo-sepolia-integration-1 --cluster-list cluster1 cluster2 -f feeder.integration-sepolia.starknet.io --project-name my-gcp-project
73+
"""
74+
75+
args_builder = ApolloArgsParserBuilder(
76+
"Restart all nodes using the value from the feeder URL",
77+
usage_example,
78+
include_restart_strategy=False,
79+
)
80+
81+
args_builder.add_argument(
82+
"-f",
83+
"--feeder-url",
84+
required=True,
85+
type=str,
86+
help="The feeder URL to get the current block from",
87+
)
88+
89+
# TODO(guy.f): Remove this when we rely on metrics for restarting.
90+
args_builder.add_argument(
91+
"--project-name",
92+
required=True,
93+
help="The name of the project to get logs from.",
94+
)
95+
96+
args = args_builder.build()
97+
98+
# Get current block number from feeder URL
99+
current_block_number = get_current_block_number(args.feeder_url)
100+
next_block_number = current_block_number + 1
101+
102+
print_colored(f"Current block number: {current_block_number}")
103+
print_colored(f"Next block number: {next_block_number}")
104+
105+
config_overrides = {
106+
"consensus_manager_config.cende_config.skip_write_height": next_block_number,
107+
"consensus_manager_config.immediate_active_height": next_block_number,
108+
}
109+
110+
namespace_list = get_namespace_list_from_args(args)
111+
context_list = get_context_list_from_args(args)
112+
if context_list is not None:
113+
assert len(namespace_list) == len(
114+
context_list
115+
), "namespace_list and context_list must have the same length"
116+
117+
# Generate logs explorer URLs if needed
118+
post_restart_instructions = []
119+
120+
for namespace, context in zip(namespace_list, context_list or [None] * len(namespace_list)):
121+
url = get_logs_explorer_url_for_proposal(
122+
namespace,
123+
get_validator_id(namespace, context),
124+
# Feeder could be behind by up to 10 blocks, so we add 10 to the current block number.
125+
current_block_number + 10,
126+
args.project_name,
127+
)
128+
post_restart_instructions.append(
129+
f"Please check logs and verify that the node has proposed a block that was accepted. Logs URL: {url}"
130+
)
131+
132+
update_config_and_restart_nodes(
133+
config_overrides,
134+
namespace_list,
135+
Service.Core,
136+
context_list,
137+
RestartStrategy.ALL_AT_ONCE,
138+
post_restart_instructions,
139+
)
140+
141+
142+
if __name__ == "__main__":
143+
main()
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
#!/usr/bin/env python3
2+
3+
import sys
4+
from typing import Optional
5+
6+
import urllib.parse
7+
from update_config_and_restart_nodes_lib import (
8+
ApolloArgsParserBuilder,
9+
RestartStrategy,
10+
Service,
11+
get_context_list_from_args,
12+
get_current_block_number,
13+
get_logs_explorer_url,
14+
get_namespace_list_from_args,
15+
print_colored,
16+
print_error,
17+
update_config_and_restart_nodes,
18+
)
19+
20+
21+
# TODO(guy.f): Remove this once we have metrics we use to decide based on.
22+
def get_logs_explorer_url_for_revert(
23+
namespace: str,
24+
block_number: int,
25+
project_name: str,
26+
) -> str:
27+
query = (
28+
f'resource.labels.namespace_name:"{urllib.parse.quote(namespace)}"\n'
29+
f'resource.labels.container_name="sequencer-core"\n'
30+
f'textPayload =~ "Done reverting.*storage up to height {block_number}"'
31+
)
32+
return get_logs_explorer_url(query, project_name)
33+
34+
35+
def set_revert_mode(
36+
namespace_list: list[str],
37+
context_list: Optional[list[str]],
38+
project_name: str,
39+
should_revert: bool,
40+
revert_up_to_block: int,
41+
restart_strategy: RestartStrategy,
42+
):
43+
config_overrides = {
44+
"revert_config.should_revert": should_revert,
45+
"revert_config.revert_up_to_and_including": revert_up_to_block,
46+
}
47+
48+
post_restart_instructions = []
49+
for namespace, context in zip(namespace_list, context_list):
50+
url = get_logs_explorer_url_for_revert(namespace, revert_up_to_block, project_name)
51+
52+
post_restart_instructions.append(
53+
f"Please check logs and verify that revert has completed (both in the batcher and for sync). Logs URL: {url}"
54+
)
55+
56+
update_config_and_restart_nodes(
57+
config_overrides,
58+
namespace_list,
59+
Service.Core,
60+
context_list,
61+
restart_strategy,
62+
post_restart_instructions,
63+
)
64+
65+
66+
def main():
67+
usage_example = """
68+
Examples:
69+
# Set revert mode up to a specific block
70+
%(prog)s --namespace apollo-sepolia-integration --num-nodes 3 -t all_at_once --revert-only --revert_up_to_block 12345
71+
%(prog)s -n apollo-sepolia-integration -N 3 -t one_by_one --revert-only -b 12345
72+
73+
# Set revert mode using feeder URL to get current block
74+
%(prog)s --namespace apollo-sepolia-integration --num-nodes 3 -t all_at_once --revert-only --feeder-url feeder.integration-sepolia.starknet.io
75+
%(prog)s -n apollo-sepolia-integration -N 3 -t one_by_one --revert-only -f feeder.integration-sepolia.starknet.io
76+
77+
# Disable revert mode
78+
%(prog)s --namespace apollo-sepolia-integration --num-nodes 3 -t all_at_once --disable-revert-only
79+
%(prog)s -n apollo-sepolia-integration -N 3 -t one_by_one --disable-revert-only
80+
81+
# Set revert mode with cluster prefix
82+
%(prog)s -n apollo-sepolia-integration -N 3 -c my-cluster -t all_at_once --revert-only -b 12345
83+
84+
# Set revert mode with feeder URL and cluster prefix
85+
%(prog)s -n apollo-sepolia-integration -N 3 -c my-cluster -t one_by_one --revert-only -f feeder.integration-sepolia.starknet.io
86+
87+
# Disable revert mode without restarting nodes
88+
%(prog)s -n apollo-sepolia-integration -N 3 -t no_restart --disable-revert-only
89+
90+
# Set revert mode with explicit restart
91+
%(prog)s -n apollo-sepolia-integration -N 3 -t all_at_once --revert-only -b 12345
92+
93+
# Set revert mode with feeder URL and explicit restart
94+
%(prog)s -n apollo-sepolia-integration -N 3 -t one_by_one --revert-only -f feeder.integration-sepolia.starknet.io
95+
96+
# Set revert mode starting from specific node index
97+
%(prog)s -n apollo-sepolia-integration -N 3 -i 5 -t all_at_once --revert-only -b 12345
98+
99+
# Set revert mode with feeder URL starting from specific node index
100+
%(prog)s -n apollo-sepolia-integration -N 3 -i 5 -t one_by_one --revert-only -f feeder.integration-sepolia.starknet.io
101+
"""
102+
103+
args_builder = ApolloArgsParserBuilder(
104+
"Sets or unsets the revert mode for the sequencer nodes", usage_example
105+
)
106+
107+
revert_group = args_builder.parser.add_mutually_exclusive_group()
108+
revert_group.add_argument("--revert-only", action="store_true", help="Enable revert mode")
109+
revert_group.add_argument(
110+
"--disable-revert-only", action="store_true", help="Disable revert mode"
111+
)
112+
113+
args_builder.add_argument(
114+
"-b",
115+
"--revert-up-to-block",
116+
type=int,
117+
help="Block number up to which to revert (inclusive). Must be a positive integer.",
118+
)
119+
120+
args_builder.add_argument(
121+
"-f",
122+
"--feeder-url",
123+
type=str,
124+
help="The feeder URL to get the current block from. We will revert all blocks above it.",
125+
)
126+
127+
# TODO(guy.f): Remove this when we rely on metrics for restarting.
128+
args_builder.add_argument(
129+
"--project-name",
130+
help="The name of the project to get logs from. If One_By_One strategy is used, this is required.",
131+
)
132+
133+
args = args_builder.build()
134+
135+
if args.restart_strategy == RestartStrategy.ONE_BY_ONE and args.project_name is None:
136+
print_error("Error: --project-name is required when using One_By_One strategy")
137+
sys.exit(1)
138+
139+
should_revert = not args.disable_revert_only
140+
if should_revert:
141+
if args.feeder_url is None and args.revert_up_to_block is None:
142+
print_error(
143+
"Error: Either --feeder-url or --revert_up_to_block (-b) are required when reverting is requested."
144+
)
145+
sys.exit(1)
146+
if args.feeder_url is not None and args.revert_up_to_block is not None:
147+
print_error("Error: Cannot specify both --feeder-url and --revert_up_to_block (-b).")
148+
sys.exit(1)
149+
150+
if args.disable_revert_only:
151+
if args.feeder_url is not None:
152+
print_error("Error: --feeder-url cannot be set when using --disable-revert-only")
153+
sys.exit(1)
154+
if args.revert_up_to_block is not None:
155+
print_error("Error: --revert-up-to-block (-b) cannot be set when disabling revert.")
156+
sys.exit(1)
157+
158+
namespace_list = get_namespace_list_from_args(args)
159+
context_list = get_context_list_from_args(args)
160+
161+
should_disable_revert = not args.revert_only
162+
if should_revert:
163+
revert_up_to_block = (
164+
args.revert_up_to_block
165+
if args.revert_up_to_block is not None
166+
else get_current_block_number(args.feeder_url)
167+
)
168+
f"\nEnabling revert mode up to (and including) block {revert_up_to_block}"
169+
set_revert_mode(
170+
namespace_list,
171+
context_list,
172+
args.project_name,
173+
True,
174+
revert_up_to_block,
175+
args.restart_strategy,
176+
)
177+
if should_disable_revert:
178+
print_colored(f"\nDisabling revert mode")
179+
# Setting to max block to max u64.
180+
set_revert_mode(
181+
namespace_list,
182+
context_list,
183+
args.project_name,
184+
False,
185+
18446744073709551615,
186+
args.restart_strategy,
187+
)
188+
189+
190+
if __name__ == "__main__":
191+
main()

0 commit comments

Comments
 (0)