Skip to content

Commit acbcf27

Browse files
Merge pull request #50 from ElrondNetwork/testnet-fixes
Testnet and other fixes
2 parents 38531bd + cb2db2d commit acbcf27

15 files changed

Lines changed: 159 additions & 47 deletions

erdpy/cli.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import erdpy.cli_transactions
2020
import erdpy.cli_validators
2121
import erdpy.cli_wallet
22-
import erdpy.cli_delagation
22+
import erdpy.cli_delegation
2323
import erdpy.cli_dns
2424
from erdpy import config, errors, scope
2525
from erdpy._version import __version__
@@ -99,7 +99,7 @@ def setup_parser(args: List[str] = sys.argv[1:]):
9999
commands.append(erdpy.cli_block.setup_parser(subparsers))
100100
commands.append(erdpy.cli_testnet.setup_parser(args, subparsers))
101101
commands.append(erdpy.cli_data.setup_parser(subparsers))
102-
commands.append(erdpy.cli_delagation.setup_parser(args, subparsers))
102+
commands.append(erdpy.cli_delegation.setup_parser(args, subparsers))
103103
commands.append(erdpy.cli_dns.setup_parser(args, subparsers))
104104

105105
parser.epilog = """

erdpy/cli_deps.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def setup_parser(subparsers: Any) -> Any:
1111
parser = cli_shared.add_group_subparser(subparsers, "deps", "Manage dependencies or elrond-sdk modules")
1212
subparsers = parser.add_subparsers()
1313

14-
choices = list(get_deps_dict().keys())
14+
choices = ['all'] + list(get_deps_dict().keys())
1515

1616
sub = cli_shared.add_command_subparser(subparsers, "deps", "install", "Install dependencies or elrond-sdk modules.")
1717
sub.add_argument("name", choices=choices, help="the dependency to install")

erdpy/config.py

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import os.path
2+
import semver
23
from typing import Any, Dict, List
4+
from pathlib import Path
35

4-
from erdpy import errors, utils
6+
from erdpy import errors, utils, workstation
57

68
ROOT_FOLDER_NAME = "elrondsdk"
79
LOCAL_CONFIG_PATH = os.path.join(os.getcwd(), "erdpy.json")
@@ -170,6 +172,8 @@ def get_defaults() -> Dict[str, Any]:
170172
"dependencies.mcl_signer.tag": "latest",
171173
"dependencies.mcl_signer.urlTemplate.linux": "https://github.com/ElrondNetwork/elrond-sdk-go-tools/releases/download/{TAG}/mcl_signer_{TAG}_ubuntu-latest.tar.gz",
172174
"dependencies.mcl_signer.urlTemplate.osx": "https://github.com/ElrondNetwork/elrond-sdk-go-tools/releases/download/{TAG}/mcl_signer_{TAG}_macos-latest.tar.gz",
175+
"testnet.validate_expected_keys": "false",
176+
"github_api_token": "",
173177
}
174178

175179

@@ -236,3 +240,44 @@ def determine_final_args(argv: List[str], config_args: Dict[str, Any]) -> List[s
236240
pre_args = [verbose_flag]
237241

238242
return pre_args + argv + extra_args
243+
244+
245+
def get_dependency_directory(key: str, tag: str) -> Path:
246+
parent_directory = get_dependency_parent_directory(key)
247+
if tag == 'latest':
248+
tag = get_latest_semver_from_directory(parent_directory)
249+
250+
return parent_directory / tag
251+
252+
253+
def get_dependency_parent_directory(key: str) -> Path:
254+
tools_folder = Path(workstation.get_tools_folder())
255+
return tools_folder / key
256+
257+
258+
def get_latest_semver_from_directory(directory: Path) -> str:
259+
subdirs = [subdir.name for subdir in directory.iterdir()]
260+
versions = parse_strings_to_semver(subdirs)
261+
if len(versions) == 0:
262+
raise Exception(f'no versions found in {directory}')
263+
264+
if len(versions) == 1:
265+
latest_version = versions[0]
266+
else:
267+
latest_version = sorted(versions).pop()
268+
return 'v' + str(latest_version)
269+
270+
271+
def parse_strings_to_semver(version_strings: List[str]) -> List[semver.VersionInfo]:
272+
versions = []
273+
for version_string in version_strings:
274+
try:
275+
# Omit the 'v' prefix of the version string
276+
version_string = version_string[1:]
277+
version = semver.VersionInfo.parse(version_string)
278+
except ValueError:
279+
continue
280+
281+
versions.append(version)
282+
283+
return versions

erdpy/dependencies/install.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import logging
2+
from pathlib import Path
23
from typing import Dict, List
34

45
from erdpy import config, errors
@@ -10,11 +11,16 @@
1011

1112

1213
def install_module(key: str, tag: str = "", overwrite: bool = False):
13-
module = get_module_by_key(key)
14-
module.install(tag, overwrite)
14+
if key == 'all':
15+
modules = get_all_deps()
16+
else:
17+
modules = [get_module_by_key(key)]
18+
19+
for module in modules:
20+
module.install(tag, overwrite)
1521

1622

17-
def get_module_directory(key: str) -> str:
23+
def get_module_directory(key: str) -> Path:
1824
module = get_module_by_key(key)
1925
default_tag = config.get_dependency_tag(key)
2026
directory = module.get_directory(default_tag)

erdpy/dependencies/modules.py

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def __init__(self, key: str, aliases: List[str]):
1515
self.key = key
1616
self.aliases = aliases
1717

18-
def get_directory(self, tag: str) -> str:
18+
def get_directory(self, tag: str) -> Path:
1919
raise NotImplementedError()
2020

2121
def install(self, tag: str, overwrite: bool) -> None:
@@ -88,7 +88,7 @@ def is_installed(self, tag: str) -> bool:
8888
def _download(self, tag: str):
8989
url = self._get_download_url(tag)
9090
archive_path = self._get_archive_path(tag)
91-
downloader.download(url, archive_path)
91+
downloader.download(url, str(archive_path))
9292

9393
def _extract(self, tag: str):
9494
archive_path = self._get_archive_path(tag)
@@ -101,26 +101,23 @@ def _extract(self, tag: str):
101101
else:
102102
raise errors.UnknownArchiveType(self.archive_type)
103103

104-
def get_directory(self, tag: str):
105-
folder = path.join(self.get_parent_directory(), tag)
106-
return folder
104+
def get_directory(self, tag: str) -> Path:
105+
return config.get_dependency_directory(self.key, tag)
107106

108107
def get_source_directory(self, tag: str):
109-
folder = Path(self.get_directory(tag))
110-
111108
# Due to how the GitHub creates archives for repository releases, the
112109
# path will contain the tag in two variants: with the 'v' prefix (e.g.
113110
# "v1.1.0"), but also without (e.g. "1.1.0"), hence the need to remove
114111
# the initial 'v'.
115-
if tag.startswith("v"):
116-
tag = tag[1:]
112+
tag_no_v = tag
113+
if tag_no_v.startswith("v"):
114+
tag_no_v = tag_no_v[1:]
117115
assert isinstance(self.repo_name, str)
118-
source_folder = folder / (self.repo_name + '-' + tag)
116+
source_folder = self.get_directory(tag) / f'{self.repo_name}-{tag_no_v}'
119117
return source_folder
120118

121-
def get_parent_directory(self):
122-
tools_folder = workstation.get_tools_folder()
123-
return path.join(tools_folder, self.key)
119+
def get_parent_directory(self) -> Path:
120+
return config.get_dependency_parent_directory(self.key)
124121

125122
def _get_download_url(self, tag: str) -> str:
126123
platform = workstation.get_platform()
@@ -140,9 +137,9 @@ def get_latest_release(self) -> str:
140137
tag = utils.query_latest_release_tag(org_repo)
141138
return tag
142139

143-
def _get_archive_path(self, tag: str) -> str:
144-
tools_folder = workstation.get_tools_folder()
145-
archive = path.join(tools_folder, f"{self.key}.{tag}.{self.archive_type}")
140+
def _get_archive_path(self, tag: str) -> Path:
141+
tools_folder = Path(workstation.get_tools_folder())
142+
archive = tools_folder / f"{self.key}.{tag}.{self.archive_type}"
146143
return archive
147144

148145

@@ -163,6 +160,7 @@ def _post_install(self, tag: str):
163160

164161
self.make_binary_symlink_in_parent_folder(tag, 'arwendebug', 'arwendebug')
165162
self.make_binary_symlink_in_parent_folder(tag, 'test', 'mandos-test')
163+
self.copy_libwasmer_in_parent_directory(tag)
166164

167165
def build_binary(self, tag, binary_name):
168166
source_folder = self.binary_source_folder(tag, binary_name)
@@ -178,12 +176,19 @@ def make_binary_symlink_in_parent_folder(self, tag, binary_name, symlink_name):
178176
source_folder = self.binary_source_folder(tag, binary_name)
179177
binary = source_folder / binary_name
180178

181-
parent = Path(self.get_parent_directory())
179+
parent = self.get_parent_directory()
182180
symlink = parent / symlink_name
183181

184182
symlink.unlink(missing_ok=True)
185183
symlink.symlink_to(binary)
186184

185+
def copy_libwasmer_in_parent_directory(self, tag):
186+
libwasmer_directory = self.get_source_directory(tag) / 'wasmer'
187+
parent_directory = self.get_parent_directory()
188+
for f in libwasmer_directory.iterdir():
189+
if f.suffix in ['.dylib', '.so', '.dll']:
190+
shutil.copy(f, parent_directory)
191+
187192
def get_env(self):
188193
return {
189194
}

erdpy/scope.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,13 @@ def initialize():
1919
if os.path.exists(testnet_toml):
2020
global chain_id, proxy
2121

22-
testnet_config = TestnetConfiguration.from_file(testnet_toml)
2322
chain_id = CHAIN_ID
24-
proxy = f"http://localhost:{testnet_config.proxy_port()}"
23+
24+
try:
25+
testnet_config = TestnetConfiguration.from_file(testnet_toml)
26+
proxy = f"http://localhost:{testnet_config.proxy_port()}"
27+
except FileNotFoundError:
28+
logger.warn("components of the testnet may be missing")
2529

2630

2731
def get_chain_id():

erdpy/testnet/config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ def __init__(self, config):
6060
folder_path = folder_path.replace('{ELRONDSDK}', str(sdk_folder))
6161

6262
default_tag = erdpy.config.get_dependency_tag(folder_key)
63+
if default_tag == 'latest':
64+
parent_folder = erdpy.config.get_dependency_parent_directory(folder_key)
65+
default_tag = erdpy.config.get_latest_semver_from_directory(parent_folder)
66+
6367
folder_path = folder_path.replace('{TAG}', default_tag)
6468

6569
# If the user has not specified a custom source repository, the

erdpy/testnet/node_config_toml.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from typing import Dict, Any
22

3+
import erdpy.config
4+
35
from erdpy.testnet.config import TestnetConfiguration
46
from erdpy.testnet.nodes_setup_json import CHAIN_ID
57

@@ -84,29 +86,34 @@ def patch_enable_epochs(data: ConfigDict, testnet_config: TestnetConfiguration):
8486
enable_epochs['BackwardCompSaveKeyValueEnableEpoch'] = 5
8587
enable_epochs['SCRSizeInvariantCheckEnableEpoch'] = 5
8688

87-
enable_epochs['MultiESDTTransferFixOnCallBackOnEnableEpoch'] = 5
88-
enable_epochs['ESDTNFTCreateOnMultiShard'] = 5
89-
enable_epochs['RemoveNonUpdatedStorageEnableEpoch'] = 5
90-
enable_epochs['FixOOGReturnCodeEnableEpoch'] = 5
91-
enable_epochs['AddTokensToDelegationEnableEpoch'] = 5
92-
enable_epochs['CorrectFirstQueuedEpoch'] = 5
93-
enable_epochs['MetaESDTSetEnableEpoch'] = 5
94-
enable_epochs['OptimizeGasUsedInCrossMiniBlocksEnableEpoch'] = 5
95-
enable_epochs['DeleteDelegatorAfterClaimRewardsEnableEpoch'] = 5
89+
enable_epochs['MultiESDTTransferFixOnCallBackOnEnableEpoch'] = 0
90+
enable_epochs['ESDTNFTCreateOnMultiShard'] = 0
91+
enable_epochs['RemoveNonUpdatedStorageEnableEpoch'] = 0
92+
enable_epochs['FixOOGReturnCodeEnableEpoch'] = 0
93+
enable_epochs['AddTokensToDelegationEnableEpoch'] = 0
94+
enable_epochs['CorrectFirstQueuedEpoch'] = 0
95+
enable_epochs['MetaESDTSetEnableEpoch'] = 0
96+
enable_epochs['OptimizeGasUsedInCrossMiniBlocksEnableEpoch'] = 0
97+
enable_epochs['DeleteDelegatorAfterClaimRewardsEnableEpoch'] = 0
9698

9799
enable_epochs['MaxNodesChangeEnableEpoch'] = [
98100
{'EpochEnable': 0, 'MaxNumNodes': 36, 'NodesToShufflePerShard': 4},
99101
{'EpochEnable': 1, 'MaxNumNodes': 56, 'NodesToShufflePerShard': 2}
100102
]
101103

102-
validate_expected_keys(data['EnableEpochs'], enable_epochs)
104+
validate = erdpy.config.get_value('testnet.validate_expected_keys') == 'true'
105+
106+
if validate:
107+
validate_expected_keys(data['EnableEpochs'], enable_epochs)
103108
data['EnableEpochs'].update(enable_epochs)
104109

105110
gas_schedule = dict()
106111
gas_schedule['GasScheduleByEpochs'] = [
107112
{'StartEpoch': 0, 'FileName': 'gasScheduleV3.toml'}
108113
]
109-
validate_expected_keys(data['GasSchedule'], gas_schedule)
114+
115+
if validate:
116+
validate_expected_keys(data['GasSchedule'], gas_schedule)
110117
data['GasSchedule'].update(gas_schedule)
111118

112119

erdpy/tests/test_modules.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import semver
2+
from erdpy.dependencies.modules import StandaloneModule
3+
4+
5+
def test_semver_parsing():
6+
v = semver.VersionInfo.parse('1.2.3')
7+
assert (v.major, v.minor, v.patch) == (1, 2, 3)
8+
9+
v = semver.VersionInfo.parse('1.2.0-beta.3')
10+
assert (v.major, v.minor, v.patch) == (1, 2, 0)
11+
assert v.prerelease == 'beta.3'
12+
13+
14+
def test_semver_sorting():
15+
folders = ['master', 'development', 'v1.2.3', 'v1.3.19', 'v0.1.1-beta.2']
16+
latest = StandaloneModule.get_latest_semver_from_folder_list(folders)
17+
assert latest == 'v1.3.19'

0 commit comments

Comments
 (0)