Skip to content

Commit

Permalink
feat: Given a day of the voting date find the hour that maximizes the…
Browse files Browse the repository at this point in the history
… probability that the upgrade happens during working hours (#12204)

Usage:

`python3 estimate_epoch_start_time.py --chain_id mainnet
--voting_date_day "2024-10-23" --timezone cet`

<details><summary>Example Output</summary>

```
Epoch -1: 13 hours, 19 minutes
Epoch -2: 13 hours, 15 minutes
Epoch -3: 13 hours, 23 minutes
Epoch -4: 13 hours, 17 minutes

Exponential weighted average epoch length: 13 hours, 18 minutes
Predicted start of epoch 1: 2024-10-22 05:18:32 CEST+0200 Tuesday
Predicted start of epoch 2: 2024-10-22 18:37:26 CEST+0200 Tuesday
Predicted start of epoch 3: 2024-10-23 07:56:19 CEST+0200 Wednesday
Predicted start of epoch 4: 2024-10-23 21:15:12 CEST+0200 Wednesday
Predicted start of epoch 5: 2024-10-24 10:34:05 CEST+0200 Thursday
Predicted start of epoch 6: 2024-10-24 23:52:58 CEST+0200 Thursday
Predicted start of epoch 7: 2024-10-25 13:11:51 CEST+0200 Friday
Predicted start of epoch 8: 2024-10-26 02:30:45 CEST+0200 Saturday
Predicted start of epoch 9: 2024-10-26 15:49:38 CEST+0200 Saturday
Predicted start of epoch 10: 2024-10-27 04:08:31 CET+0100 Sunday

Voting hours on 2024-10-23 UTC that result in upgrade during working hours (UTC 8:00-22:00):
- 00:00, Upgrade Epoch: 4
- 01:00, Upgrade Epoch: 4
- 02:00, Upgrade Epoch: 4
- 03:00, Upgrade Epoch: 4
- 04:00, Upgrade Epoch: 4
- 05:00, Upgrade Epoch: 4
- 06:00, Upgrade Epoch: 5
- 07:00, Upgrade Epoch: 5
- 08:00, Upgrade Epoch: 5
- 09:00, Upgrade Epoch: 5
- 10:00, Upgrade Epoch: 5
- 11:00, Upgrade Epoch: 5
- 12:00, Upgrade Epoch: 5
- 13:00, Upgrade Epoch: 5
- 14:00, Upgrade Epoch: 5
- 15:00, Upgrade Epoch: 5
- 16:00, Upgrade Epoch: 5
- 17:00, Upgrade Epoch: 5
- 18:00, Upgrade Epoch: 5
- 19:00, Upgrade Epoch: 5
``` 

</details>
  • Loading branch information
stedfn authored Oct 28, 2024
1 parent 244422d commit 3f3a078
Showing 1 changed file with 61 additions and 3 deletions.
64 changes: 61 additions & 3 deletions debug_scripts/estimate_epoch_start_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,54 @@ def find_epoch_for_timestamp(future_epochs, voting_timestamp):
return len(future_epochs)


def find_best_voting_hour(voting_date_str, future_epochs):
# Working hours during which there are available NEAR engineers
WORKING_HOURS_START = 8 # 8:00 UTC
WORKING_HOURS_END = 22 # 22:00 UTC

valid_hours = []

for hour in range(24):
# Construct datetime for each hour of the voting date
voting_datetime = datetime.strptime(
f"{voting_date_str} {hour:02d}:00:00", '%Y-%m-%d %H:%M:%S')
voting_datetime = pytz.utc.localize(voting_datetime)
voting_timestamp = voting_datetime.timestamp()

# Find the epoch T in which the voting date falls
epoch_T = find_epoch_for_timestamp(future_epochs, voting_timestamp)
if epoch_T <= 0:
continue # Voting date is before the first predicted epoch

# Calculate when the protocol upgrade will happen (start of epoch T+2)
protocol_upgrade_epoch_number = epoch_T + 2
if protocol_upgrade_epoch_number > len(future_epochs):
print(
"Not enough future epochs predicted to determine all the protocol upgrade times."
)
break

protocol_upgrade_timestamp = future_epochs[protocol_upgrade_epoch_number
- 1]
protocol_upgrade_datetime = datetime.fromtimestamp(
protocol_upgrade_timestamp)
upgrade_hour_utc = protocol_upgrade_datetime.hour

if WORKING_HOURS_START <= upgrade_hour_utc < WORKING_HOURS_END:
valid_hours.append((hour, protocol_upgrade_epoch_number))

if valid_hours:
print(
f"\nVoting hours on {voting_date_str} UTC that result in upgrade during working hours (UTC {WORKING_HOURS_START}:00-{WORKING_HOURS_END}:00):"
)
for (hour, epoch) in valid_hours:
print(f"- {hour:02d}:00, Upgrade Epoch: {epoch}")
else:
print(
"\nNo voting hours on the given date result in an upgrade during working hours."
)


def valid_voting_datetime(s):
try:
dt = datetime.strptime(s, '%Y-%m-%d %H:%M:%S')
Expand Down Expand Up @@ -178,6 +226,8 @@ def main(args):
if args.voting_date:
find_protocol_upgrade_time(args.voting_date, future_epochs,
args.timezone)
elif args.voting_date_day:
find_best_voting_hour(args.voting_date_day, future_epochs)


# Custom action to set the URL based on chain_id
Expand Down Expand Up @@ -222,9 +272,17 @@ def __call__(self, parser, namespace, values, option_string=None):
type=valid_timezone,
default="UTC",
help="Time zone to display times in (e.g., 'America/New_York').")
parser.add_argument("--voting_date",
type=valid_voting_datetime,
help="Voting date in 'YYYY-MM-DD HH:MM:SS' format.")
# Voting date arguments
voting_group = parser.add_mutually_exclusive_group()
voting_group.add_argument(
"--voting_date",
type=valid_voting_datetime,
help="Voting date in 'YYYY-MM-DD HH:MM:SS' format.")
voting_group.add_argument(
"--voting_date_day",
help=
"Voting date (day) in 'YYYY-MM-DD' format to find voting hours resulting in upgrade during working hours."
)

args = parser.parse_args()
main(args)

0 comments on commit 3f3a078

Please sign in to comment.