Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ small.label {
}
</style>

## 4.22.1 <small>(Mar 2, 2026)</small> { id="4.22.1" }

Fixes & improvements:

- added support for Solidity 0.8.34 <small class="label">[core]</small>
- fixed solc JSON list fetching crashing due to missing User-Agent header <small class="label">[core]</small>
- fixed remapping rules inconsistent with solc leading to compilation crashes <small class="label">[core]</small>
- fixed compilation crashes caused by multiple symlinks pointing to the same file <small class="label">[core]</small>
- fixed `AbstractChildWatcher` no longer present in Python 3.14 <small class="label">[core]</small>

## 4.22.0 <small>(Jan 3, 2026)</small> { id="4.22.0" }

Features & improvements:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "eth-wake"
version = "4.22.0"
version = "4.22.1"
description = "Wake is a Python-based Solidity development and testing framework with built-in vulnerability detectors."
license = "ISC"
authors = ["Ackee Blockchain"]
Expand Down
4 changes: 2 additions & 2 deletions wake/cli/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from .svm import run_svm
from .test import run_test

if platform.system() != "Windows":
if platform.system() != "Windows" and sys.version_info < (3, 12):
try:
from asyncio import (
ThreadedChildWatcher, # pyright: ignore reportGeneralTypeIssues
Expand Down Expand Up @@ -206,7 +206,7 @@ def exit():

if platform.system() == "Windows":
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
else:
elif sys.version_info < (3, 12):
asyncio.get_event_loop_policy().set_child_watcher(
ThreadedChildWatcher() # pyright: ignore reportUnboundVariable
)
Expand Down
4 changes: 2 additions & 2 deletions wake/compiler/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,9 +400,9 @@ def build_graph(
source_units: Dict[str, Path] = {}

# for every source file resolve a source unit name
for file in files:
# resolve and deduplicate (avoid duplicates due to symlinks)
for file in {f.resolve() for f in files}:
try:
file = file.resolve()
if file not in modified_files:
file = file.resolve(strict=True)
except FileNotFoundError:
Expand Down
2 changes: 1 addition & 1 deletion wake/config/wake_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ def max_solidity_version(self) -> SolidityVersion:
Returns:
Maximum supported Solidity version.
"""
return SolidityVersion.fromstring("0.8.33")
return SolidityVersion.fromstring("0.8.34")

@property
def detectors(self) -> DetectorsConfig:
Expand Down
17 changes: 14 additions & 3 deletions wake/svm/svm.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from wake.config import UnsupportedPlatformError, WakeConfig
from wake.core import get_logger
from wake.core.solidity_version import SolidityVersion
from wake.utils.version import get_package_version

from .abc import CompilerVersionManagerAbc
from .exceptions import ChecksumError, UnsupportedVersionError
Expand Down Expand Up @@ -58,6 +59,7 @@ class SolcVersionManager(CompilerVersionManagerAbc):
__solc_list_path: Path
__solc_builds: Optional[SolcBuilds]
__list_force_loaded: bool
__headers: Dict[str, str]

def __init__(self, wake_config: WakeConfig):
system = platform.system()
Expand All @@ -84,6 +86,9 @@ def __init__(self, wake_config: WakeConfig):
self.__solc_list_path = self.__compilers_path / "solc.json"
self.__solc_builds = None
self.__list_force_loaded = False
self.__headers = {
"User-Agent": f"wake/{get_package_version('eth-wake')}",
}

self.__compilers_path.mkdir(parents=True, exist_ok=True)

Expand Down Expand Up @@ -230,7 +235,7 @@ async def __download_file(
http_session: aiohttp.ClientSession,
progress: Optional[Callable[[int, int], Awaitable[None]]] = None,
) -> None:
async with http_session.get(url) as r:
async with http_session.get(url, headers=self.__headers) as r:
total_size = r.headers.get("Content-Length")
if total_size is not None:
total_size = int(total_size)
Expand Down Expand Up @@ -298,7 +303,10 @@ def __fetch_list_file(
try:
logger.debug(f"Downloading solc list from {self.__solc_list_urls[0]}")
with urllib.request.urlopen(
self.__solc_list_urls[0], timeout=5
urllib.request.Request(
self.__solc_list_urls[0], headers=self.__headers
),
timeout=5,
) as response:
json = response.read()
self.__solc_builds = SolcBuilds.model_validate_json(json)
Expand All @@ -312,7 +320,10 @@ def __fetch_list_file(
try:
logger.debug(f"Downloading solc list from {self.__solc_list_urls[1]}")
with urllib.request.urlopen(
self.__solc_list_urls[1], timeout=0.5
urllib.request.Request(
self.__solc_list_urls[1], headers=self.__headers
),
timeout=0.5,
) as response:
json = response.read()
self.__solc_builds = SolcBuilds.model_validate_json(json)
Expand Down
2 changes: 2 additions & 0 deletions wake/utils/threaded_child_watcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

"""
Backported ThreadedChildWatcher implementation from https://github.com/python/cpython/blob/5f0fe8ec70120f4586d08978b0911b436f82c421/Lib/asyncio/unix_events.py#L1326

Only to be imported if Python < 3.12.
"""


Expand Down
Loading