Skip to content

Commit 7653a6d

Browse files
committed
Update dev-net to run on latest changes
1 parent e429f1f commit 7653a6d

File tree

4 files changed

+81
-51
lines changed

4 files changed

+81
-51
lines changed

src/network_config/localdev.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ inline constexpr network_config config{
4343
.UPTIME_PROOF_FREQUENCY = testnet::config.UPTIME_PROOF_FREQUENCY,
4444
.UPTIME_PROOF_VALIDITY = testnet::config.UPTIME_PROOF_VALIDITY,
4545
.MAX_DEACTIVATE_PER_BLOCK = testnet::config.MAX_DEACTIVATE_PER_BLOCK,
46-
.HAVE_STORAGE_SERVER = false,
46+
.HAVE_STORAGE_SERVER = true,
4747
.HAVE_SESSION_ROUTER = false,
4848
.HAVE_LOKINET = false,
4949
.TARGET_BLOCK_TIME = TARGET_BLOCK_TIME,

src/oxen_economy.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ inline constexpr size_t MAX_CONTRIBUTORS_V1 = 4;
5959
// SESH staking requirement starting at HF20
6060
inline constexpr uint64_t SESH_STAKING_REQUIREMENT = 25'000 * COIN;
6161
inline constexpr uint64_t SESH_STAKING_REQUIREMENT_TESTNET = 20'000 * COIN;
62-
inline constexpr uint64_t SESH_STAKING_REQUIREMENT_LOCALDEV = 20'000 * COIN;
62+
inline constexpr uint64_t SESH_STAKING_REQUIREMENT_LOCALDEV = 120 * COIN;
6363

6464
// Initial SESH reward for the first few blocks of HF21 (before there are L2_REWARD_CONSENSUS_BLOCKS
6565
// blocks to achieve reward consensus). This value is based on a 40M initial reward pool with 15.1%

utils/local-devnet/daemons.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ def start_storage_server(self):
244244
"--log-level=trace",
245245
]
246246
print("Starting storage server: ", args)
247-
self.storage_server_proc = subprocess.Popen(args, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
247+
self.storage_server_proc = subprocess.Popen(args, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
248248

249249
def stop_storage_server(self):
250250
if self.storage_server_proc:
@@ -352,7 +352,9 @@ def txpool_hashes(self):
352352
def ping(self, *, storage=True, lokinet=True):
353353
"""Sends fake storage server and lokinet pings to the running oxend"""
354354
if storage:
355-
self.json_rpc("storage_server_ping", { "version": [2, 5, 0], "https_port": 0, "omq_port": 0, "pubkey_ed25519": self.get_service_keys().ed25519_pubkey})
355+
# NOTE: A fake storage ping needs to set the HTTPS/OMQ port to a non-zero value for it to
356+
# be accepted by the network
357+
self.json_rpc("storage_server_ping", { "version": [2, 5, 0], "https_port": 1, "omq_port": 1, "pubkey_ed25519": self.get_service_keys().ed25519_pubkey})
356358
if lokinet:
357359
self.json_rpc("lokinet_ping", { "version": [9,9,9] })
358360

utils/local-devnet/service_node_network.py

Lines changed: 75 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def coins(*args):
5555
return round(x * 1000000000)
5656

5757

58-
def wait_for(callback, timeout=10):
58+
def wait_for(callback, timeout=10, sleep_s=.25):
5959
expires = time.time() + timeout
6060
while True:
6161
try:
@@ -65,7 +65,7 @@ def wait_for(callback, timeout=10):
6565
pass
6666
if time.time() >= expires:
6767
raise RuntimeError("task timeout expired")
68-
time.sleep(.25)
68+
time.sleep(sleep_s)
6969

7070

7171
verbose = True
@@ -783,6 +783,35 @@ class SNNetwork:
783783
eth_sns: list[Daemon] = []
784784
wallets = []
785785

786+
def startup_storage_servers(self, storage_server_path: pathlib.Path):
787+
if storage_server_path:
788+
vprint("Starting storage server")
789+
for n in self.all_nodes:
790+
if n.service_node:
791+
n.start_storage_server();
792+
793+
vprint("Waiting for proofs with storage ports to propagate:", flush=True)
794+
while True:
795+
for sn in self.sns:
796+
sn.send_uptime_proof()
797+
798+
all_ports_received = True
799+
for sn in self.sns:
800+
response = sn.json_rpc("get_n_service_nodes", {"fields": {"storage_port": True}}).json()['result']['service_node_states']
801+
print(response)
802+
for obj in response:
803+
if obj['storage_port'] <= 0:
804+
all_ports_received = False
805+
break
806+
807+
if all_ports_received == False:
808+
break
809+
810+
if all_ports_received == True:
811+
break
812+
813+
time.sleep(5)
814+
786815
def __init__(self,
787816
datadir,
788817
*,
@@ -832,6 +861,10 @@ def __init__(self,
832861
else:
833862
break
834863

864+
# NOTE: Mine at least one block on the EVM chain because uptime proofs from nodes take that
865+
# L2 height and that height must be > 0
866+
ethereum.evm_mine()
867+
835868
# Attempt to restore chain from cache if requested and cache is avail
836869
chain_bootstrapped_from_cache = False
837870
cache_dir = os.path.join(self.data_dir, CACHE_AT_HF20_DIR_NAME)
@@ -953,6 +986,7 @@ def __init__(self,
953986
with open(config_file, 'w') as file:
954987
file.write('#!/usr/bin/python3\n# -*- coding: utf-8 -*-\nlisten_ip=\"{}\"\nlisten_port=\"{}\"\nwallet_listen_ip=\"{}\"\nwallet_listen_port=\"{}\"\nwallet_address=\"{}\"\nexternal_address=\"{}\"'.format(self.sns[0].listen_ip,self.sns[0].rpc_port,self.mike.listen_ip,self.mike.rpc_port,self.mike.address(),self.bob.address()))
955988

989+
storage_servers_started = False
956990
if not chain_bootstrapped_from_cache:
957991
# Start blockchain setup ###################################################################
958992
# Mine some blocks; we need 100 per SN registration, and we can nearly 600 on fakenet before
@@ -1007,14 +1041,19 @@ def __init__(self,
10071041
# Submit block to enter the BLS transition ##################################################
10081042
self.sync_nodes(self.mine(1), timeout=120) # Height 170
10091043

1010-
vprint("Sending fake lokinet/ss pings and uptime proofs w/ BLS keys at HF20")
1044+
# NOTE: Start storage server
1045+
if storage_server_path and not storage_servers_started:
1046+
storage_servers_started = True
1047+
self.startup_storage_servers(storage_server_path)
1048+
1049+
vprint("Sending fake lokinet pings and uptime proofs w/ BLS keys at HF20")
10111050
for sn in self.sns:
1012-
sn.ping()
1051+
sn.ping(storage=not storage_servers_started)
10131052
sn.send_uptime_proof()
10141053

10151054
vprint("Waiting for proofs to propagate:", flush=True)
10161055
for sn in self.sns:
1017-
wait_for(lambda: all_service_nodes_proofed(sn), timeout=120)
1056+
wait_for(lambda: all_service_nodes_proofed(sn), timeout=120, sleep_s = 5)
10181057
vprint(timestamp=False)
10191058

10201059
if cache_at_hf20:
@@ -1027,10 +1066,14 @@ def __init__(self,
10271066
else:
10281067
shutil.copytree(src, dest, ignore=shutil.ignore_patterns("*.sock"), dirs_exist_ok=True)
10291068

1030-
vprint("Sending fake lokinet/ss pings and uptime proofs")
1069+
vprint("Sending fake lokinet pings")
10311070
for sn in self.sns:
1032-
sn.ping()
1033-
sn.send_uptime_proof()
1071+
sn.ping(storage=not storage_servers_started)
1072+
1073+
# NOTE: Start storage server
1074+
if storage_server_path and not storage_servers_started:
1075+
storage_servers_started = True
1076+
self.startup_storage_servers(storage_server_path)
10341077

10351078
vprint("Waiting for proofs to propagate:", flush=True)
10361079
for sn in self.sns:
@@ -1046,33 +1089,6 @@ def __init__(self,
10461089
test_bls_claim_rewards(eth_sns=self.eth_sns, sn_contract=self.sn_contract, sent_contract=self.sent_contract, staker=staker, beneficiary=beneficiary);
10471090
test_sn_exits_by_request_signature_and_liquidation(eth_sns=self.eth_sns, sn_contract=self.sn_contract, staker=staker);
10481091

1049-
# NOTE: Start storage server
1050-
if storage_server_path:
1051-
for n in self.all_nodes:
1052-
if n.service_node:
1053-
n.start_storage_server();
1054-
1055-
vprint("Waiting for proofs with storage ports to propagate:", flush=True)
1056-
while True:
1057-
for sn in self.sns:
1058-
sn.send_uptime_proof()
1059-
1060-
all_ports_received = True
1061-
for sn in self.sns:
1062-
response = sn.json_rpc("get_n_service_nodes", {"fields": {"storage_port": True}}).json()['result']['service_node_states']
1063-
for obj in response:
1064-
if obj['storage_port'] <= 0:
1065-
all_ports_received = False
1066-
break
1067-
1068-
if all_ports_received == False:
1069-
break
1070-
1071-
if all_ports_received == True:
1072-
break
1073-
1074-
time.sleep(5)
1075-
10761092
wallet_rows: list[list[str]] = []
10771093
wallet_rows.append(["Name", "Address", "Balance", "Unlocked", "Command"])
10781094
all_wallets_sorted_by_name = sorted(self.wallets + self.extrawallets, key=lambda n: n.name)
@@ -1314,12 +1330,23 @@ def do_hf21_transition(self):
13141330
if not get_info.pulse:
13151331
self.sync_nodes(self.mine(1), timeout=10)
13161332

1317-
# Wait for pulse to make block to enter BLS hardfork (height 171 or length 172)
1333+
# TODO: This previously was height 172, but, for some reason pulse stops generating blocks.
1334+
# Something seemed to stop working with inter-node communication in the quorum. Not sure
1335+
# what this is but this is not necessary for the usecase of spinning up a network. It does
1336+
# just mean that the chain doesn't advance but we are using the network for sending Session
1337+
# messages not add or deregister nodes from the network. Oddly enough, _sometimes_ on very
1338+
# rare occasion Pulse does work and blocks are generating kind of suggesting there's some
1339+
# race condition.
1340+
vprint("Wait for pulse to make block to enter BLS hardfork (height 170 or length 171)")
13181341
# Wait for one specific node to hit HF21 and check post-fork eth balance
1319-
h = self.sns[0].height()
1320-
while h < 172:
1342+
h = self.sns[0].height()
1343+
prev_height = 0
1344+
while h < 170:
13211345
time.sleep(0.25)
13221346
h = self.sns[0].height()
1347+
if prev_height != h:
1348+
prev_height = h
1349+
vprint("Height was: ", h)
13231350

13241351
# FIXME: this expected value needs to be recomputed with respect to changes made in preparation for HF21
13251352
# if integration_tests:
@@ -1329,7 +1356,7 @@ def do_hf21_transition(self):
13291356
#assert rewards_response.balance == transition_balance_expected, "Expected {} to have balance {}, not {}".format(transition_eth_addr_no_0x, transition_balance_expected, rewards_response.balance)
13301357

13311358
# Wait for all nodes to sync up
1332-
self.sync_nodes(172, timeout=120)
1359+
self.sync_nodes(170, timeout=120)
13331360

13341361
# Register a SN via the Ethereum smart contract, half as multi-contrib,
13351362
# half as solo nodes.
@@ -1391,6 +1418,7 @@ def do_hf21_transition(self):
13911418
# multi-contrib contracts
13921419
beneficiary_required_sent: int = int((contract_staking_requirement / 2) * len(self.sn_contrib_factory.deployedContracts))
13931420

1421+
print("Contract staking requirement is {}".format(contract_staking_requirement))
13941422
print("HH Account 0 Balance: {} $SENT".format(self.sent_contract.balanceOf(address=self.sn_contract.hardhat_account0.address)))
13951423
print("HH Account 1 Balance: {} $SENT".format(self.sent_contract.balanceOf(address=self.sn_contract.hardhat_account1.address)))
13961424

@@ -1521,14 +1549,14 @@ def run():
15211549
else:
15221550
shutil.rmtree(path)
15231551

1524-
snn = SNNetwork(datadir=args.data_dir,
1525-
oxen_bin_dir=args.oxen_bin_dir,
1526-
anvil_path=args.anvil_path,
1527-
session_token_contracts_dir=args.session_token_contracts_dir,
1528-
storage_server_path=args.storage_server_path,
1529-
cache_at_hf20=args.cache_at_hf20,
1530-
integration_tests=args.integration_tests,
1531-
listen_ip=args.listen_ip)
1552+
snn = SNNetwork(datadir = args.data_dir,
1553+
oxen_bin_dir = args.oxen_bin_dir,
1554+
anvil_path = args.anvil_path,
1555+
session_token_contracts_dir = args.session_token_contracts_dir,
1556+
storage_server_path = args.storage_server_path,
1557+
cache_at_hf20 = args.cache_at_hf20,
1558+
integration_tests = args.integration_tests,
1559+
listen_ip = args.listen_ip)
15321560
else:
15331561
vprint("reusing SNN")
15341562
snn.alice.new_wallet()

0 commit comments

Comments
 (0)