From 6af97171a5435b751421661a4a5b0c1c533daa5a Mon Sep 17 00:00:00 2001 From: banteg <4562643+banteg@users.noreply.github.com> Date: Fri, 10 May 2024 04:48:37 +0400 Subject: [PATCH 01/51] fix: crash when waiting for a tx confirmation --- brownie/network/transaction.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/brownie/network/transaction.py b/brownie/network/transaction.py index 9e561f65e..7926a0ca6 100644 --- a/brownie/network/transaction.py +++ b/brownie/network/transaction.py @@ -216,10 +216,10 @@ def __init__( # await confirmation of tx in a separate thread which is blocking if # required_confs > 0 or tx has already confirmed (`blockNumber` != None) confirm_thread = threading.Thread( - target=self._await_confirmation, args=(tx["blockNumber"], required_confs), daemon=True + target=self._await_confirmation, args=(tx.get("blockNumber"), required_confs), daemon=True ) confirm_thread.start() - if is_blocking and (required_confs > 0 or tx["blockNumber"]): + if is_blocking and (required_confs > 0 or tx.get("blockNumber")): confirm_thread.join() def __repr__(self) -> str: @@ -508,7 +508,7 @@ def _await_confirmation(self, block_number: int = None, required_confs: int = 1) # check if tx is still in mempool, this will raise otherwise tx = web3.eth.get_transaction(self.txid) self.block_number = None - return self._await_confirmation(tx["blockNumber"], required_confs) + return self._await_confirmation(tx.get("blockNumber"), required_confs) if required_confs - self.confirmations != remaining_confs: remaining_confs = required_confs - self.confirmations if not self._silent: From 5b3cad35005f942327b4ef4083494ee304546c79 Mon Sep 17 00:00:00 2001 From: Cowboy Date: Wed, 22 May 2024 14:10:44 +0000 Subject: [PATCH 02/51] fix: search parent paths for import file --- brownie/project/flattener.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/brownie/project/flattener.py b/brownie/project/flattener.py index 2d77bf5d0..bd0a2835d 100644 --- a/brownie/project/flattener.py +++ b/brownie/project/flattener.py @@ -147,4 +147,11 @@ def make_import_absolute(import_path: str, source_file_dir: str) -> str: if path.is_absolute(): return path.as_posix() - return (Path(source_file_dir) / path).resolve().as_posix() + source_file_dir = Path(source_file_dir).resolve() + newpath = (source_file_dir / path).resolve() + while not newpath.exists(): + source_file_dir = source_file_dir.parent + newpath = (source_file_dir / path).resolve() + if source_file_dir == Path("/"): + raise FileNotFoundError(f"Cannot determine location of {import_path}") + return newpath.as_posix() From ad4beea3046e0177c6260ed18c771d9ba503fa48 Mon Sep 17 00:00:00 2001 From: Ben Hauser Date: Thu, 23 May 2024 00:14:41 +0400 Subject: [PATCH 03/51] chore: lint --- brownie/network/transaction.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/brownie/network/transaction.py b/brownie/network/transaction.py index 7926a0ca6..138402fa1 100644 --- a/brownie/network/transaction.py +++ b/brownie/network/transaction.py @@ -216,7 +216,9 @@ def __init__( # await confirmation of tx in a separate thread which is blocking if # required_confs > 0 or tx has already confirmed (`blockNumber` != None) confirm_thread = threading.Thread( - target=self._await_confirmation, args=(tx.get("blockNumber"), required_confs), daemon=True + target=self._await_confirmation, + args=(tx.get("blockNumber"), required_confs), + daemon=True, ) confirm_thread.start() if is_blocking and (required_confs > 0 or tx.get("blockNumber")): From ef47c3602a6bf976ea44556c83a3d0e2f0ccac94 Mon Sep 17 00:00:00 2001 From: Ben Hauser Date: Thu, 23 May 2024 00:18:35 +0400 Subject: [PATCH 04/51] release: update changelog, bump version to v1.20.5 --- CHANGELOG.md | 5 +++++ brownie/_config.py | 2 +- setup.cfg | 2 +- setup.py | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6473f5b86..824351381 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://github.com/eth-brownie/brownie) +## [1.20.5](https://github.com/eth-brownie/brownie/tree/v1.20.5) - 2024-05-22 +### Fixed +- Handle missing `blockNumber` while awaiting confirmation ([#1774](https://github.com/eth-brownie/brownie/pull/1774)) +- Search parent paths for file import during source verification ([#1776](https://github.com/eth-brownie/brownie/pull/1776)) + ## [1.20.4](https://github.com/eth-brownie/brownie/tree/v1.20.4) - 2024-05-08 ### Fixed - Fall back to ABI when `Contract.from_explorer` compilation fails ([#1772](https://github.com/eth-brownie/brownie/pull/1772)) diff --git a/brownie/_config.py b/brownie/_config.py index f17b9a02f..2159a892e 100644 --- a/brownie/_config.py +++ b/brownie/_config.py @@ -19,7 +19,7 @@ from brownie._expansion import expand_posix_vars from brownie._singleton import _Singleton -__version__ = "1.20.4" +__version__ = "1.20.5" BROWNIE_FOLDER = Path(__file__).parent DATA_FOLDER = Path.home().joinpath(".brownie") diff --git a/setup.cfg b/setup.cfg index 05091dbc0..6fed16208 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 1.20.4 +current_version = 1.20.5 [bumpversion:file:setup.py] diff --git a/setup.py b/setup.py index 16a135c60..5ffa3870b 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ setup( name="eth-brownie", packages=find_packages(), - version="1.20.4", # don't change this manually, use bumpversion instead + version="1.20.5", # don't change this manually, use bumpversion instead license="MIT", description="A Python framework for Ethereum smart contract deployment, testing and interaction.", # noqa: E501 long_description=long_description, From c76077d010a1e9b6255a848c38cf18af3e8973e1 Mon Sep 17 00:00:00 2001 From: snoppy Date: Sat, 25 May 2024 20:51:03 +0800 Subject: [PATCH 05/51] chore: fix typos Signed-off-by: snoppy --- brownie/network/contract.py | 8 ++++---- brownie/project/flattener.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/brownie/network/contract.py b/brownie/network/contract.py index 1a060eb90..bc27021b6 100644 --- a/brownie/network/contract.py +++ b/brownie/network/contract.py @@ -1258,7 +1258,7 @@ def subscribe( ) -> None: """ Subscribe to event with a name matching 'event_name', calling the 'callback' - function on new occurence giving as parameter the event log receipt. + function on new occurrence giving as parameter the event log receipt. Args: event_name (str): Name of the event to subscribe to. @@ -1285,10 +1285,10 @@ def get_sequence( Returns: if 'event_type' is specified: - [list]: List of events of type 'event_type' that occured between + [list]: List of events of type 'event_type' that occurred between 'from_block' and 'to_block'. else: - event_logbook [dict]: Dictionnary of events of the contract that occured + event_logbook [dict]: Dictionary of events of the contract that occurred between 'from_block' and 'to_block'. """ if to_block is None or to_block > web3.eth.block_number: @@ -1315,7 +1315,7 @@ def listen(self, event_name: str, timeout: float = 0) -> Coroutine: 'event_name' occurs. If timeout is superior to zero and no event matching 'event_name' has occured, the Coroutine ends when the timeout is reached. - The Coroutine return value is an AttributeDict filled with the following fileds : + The Coroutine return value is an AttributeDict filled with the following fields : - 'event_data' (AttributeDict): The event log receipt that was caught. - 'timed_out' (bool): False if the event did not timeout, else True diff --git a/brownie/project/flattener.py b/brownie/project/flattener.py index bd0a2835d..08f2650cd 100644 --- a/brownie/project/flattener.py +++ b/brownie/project/flattener.py @@ -87,7 +87,7 @@ def flattened_source(self) -> str: # all pragma statements, we already have the license used + know which compiler # version is used via the build info pragmas = set((match.strip() for src in sources for match in PRAGMA_PATTERN.findall(src))) - # now we go thorugh and remove all imports/pragmas/license stuff + # now we go through and remove all imports/pragmas/license stuff wipe = lambda src: PRAGMA_PATTERN.sub( # noqa: E731 "", LICENSE_PATTERN.sub("", IMPORT_PATTERN.sub("", src)) ) From 38d74a51e1bc723a423432f8482c8b6ae9d4e94f Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Sat, 25 May 2024 12:41:05 -0400 Subject: [PATCH 06/51] feat(type): overloads for `strategy` kwargs --- brownie/test/strategies.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/brownie/test/strategies.py b/brownie/test/strategies.py index 136fa0890..87d1408ff 100644 --- a/brownie/test/strategies.py +++ b/brownie/test/strategies.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 -from typing import Any, Callable, Iterable, Optional, Tuple, Union +from typing import Any, Callable, Iterable, Optional, Tuple, Union, overload from eth_abi.grammar import BasicType, TupleType, parse from hypothesis import strategies as st @@ -16,6 +16,17 @@ ArrayLengthType = Union[int, list, None] NumberType = Union[float, int, None] +EvmIntType = Literal[ + "int8", "int16", "int24", "int32", "int40", "int48", "int56", "int64", "int72", "int80", "int88", "int96", + "int104", "int112", "int120", "int128", "int136", "int144", "int152", "int160", "int168", "int176", "int184", + "int192", "int200", "int208", "int216", "int224", "int232", "int240", "int248", "int256" +] + +EvmUintType = Literal[ + "uint8", "uint16", "uint24", "uint32", "uint40", "uint48", "uint56", "uint64", "uint72", "uint80", "uint88", "uint96", + "uint104", "uint112", "uint120", "uint128", "uint136", "uint144", "uint152", "uint160", "uint168", "uint176", "uint184", + "uint192", "uint200", "uint208", "uint216", "uint224", "uint232", "uint240", "uint248", "uint256" +] class _DeferredStrategyRepr(DeferredStrategy): def __init__(self, fn: Callable, repr_target: str) -> None: @@ -76,9 +87,9 @@ def _decimal_strategy( @_exclude_filter -def _address_strategy(length: Optional[int] = None) -> SearchStrategy: +def _address_strategy(length: Optional[int] = None, include: list = []) -> SearchStrategy: return _DeferredStrategyRepr( - lambda: st.sampled_from(list(network.accounts)[:length]), "accounts" + lambda: st.sampled_from(list(network.accounts)[:length] + include), "accounts" ) @@ -152,7 +163,12 @@ def _contract_deferred(name): return _DeferredStrategyRepr(lambda: _contract_deferred(contract_name), contract_name) - +@overload +def strategy(type_str: Literal["address"], length: Optional[int] = None, include: list = []): + ... +@overload +def strategy(type_str: Union[EvmIntType, EvmUintType], min_value: Optional[int] = None, max_value: Optional[int] = None): + ... def strategy(type_str: str, **kwargs: Any) -> SearchStrategy: type_str = TYPE_STR_TRANSLATIONS.get(type_str, type_str) if type_str == "fixed168x10": From d9926ecc5939f2ce8f120ec3c52ebfad77c8cb0f Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Tue, 28 May 2024 17:00:40 -0400 Subject: [PATCH 07/51] fix: missing import --- brownie/test/strategies.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brownie/test/strategies.py b/brownie/test/strategies.py index 87d1408ff..4888036b6 100644 --- a/brownie/test/strategies.py +++ b/brownie/test/strategies.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 -from typing import Any, Callable, Iterable, Optional, Tuple, Union, overload +from typing import Any, Callable, Iterable, Literal, Optional, Tuple, Union, overload from eth_abi.grammar import BasicType, TupleType, parse from hypothesis import strategies as st From 84810c58b617741574b7daf665956fb26850d19e Mon Sep 17 00:00:00 2001 From: banteg <4562643+banteg@users.noreply.github.com> Date: Thu, 30 May 2024 17:15:33 +0400 Subject: [PATCH 08/51] fix: ds-note decoding --- brownie/network/event.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brownie/network/event.py b/brownie/network/event.py index 437a0658a..ed0c6fd39 100644 --- a/brownie/network/event.py +++ b/brownie/network/event.py @@ -502,7 +502,7 @@ def _decode_ds_note(log, contract): # type: ignore if selector.hex() not in contract.selectors or sum(tail): return name = contract.selectors[selector.hex()] - data = bytes.fromhex(log.data[2:]) + data = bytes.fromhex(log.data[2:]) if isinstance(log.data, str) else log.data # data uses ABI encoding of [uint256, bytes] or [bytes] in different versions # instead of trying them all, assume the payload starts from selector try: From 1ec832d24cb64d4de5d5202692477ee65522af25 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Thu, 30 May 2024 12:39:25 -0400 Subject: [PATCH 09/51] chore: refactor out big ugly Literals with genexp --- brownie/test/strategies.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/brownie/test/strategies.py b/brownie/test/strategies.py index 4888036b6..df893b6ef 100644 --- a/brownie/test/strategies.py +++ b/brownie/test/strategies.py @@ -15,18 +15,8 @@ ArrayLengthType = Union[int, list, None] NumberType = Union[float, int, None] - -EvmIntType = Literal[ - "int8", "int16", "int24", "int32", "int40", "int48", "int56", "int64", "int72", "int80", "int88", "int96", - "int104", "int112", "int120", "int128", "int136", "int144", "int152", "int160", "int168", "int176", "int184", - "int192", "int200", "int208", "int216", "int224", "int232", "int240", "int248", "int256" -] - -EvmUintType = Literal[ - "uint8", "uint16", "uint24", "uint32", "uint40", "uint48", "uint56", "uint64", "uint72", "uint80", "uint88", "uint96", - "uint104", "uint112", "uint120", "uint128", "uint136", "uint144", "uint152", "uint160", "uint168", "uint176", "uint184", - "uint192", "uint200", "uint208", "uint216", "uint224", "uint232", "uint240", "uint248", "uint256" -] +EvmIntType = Literal[tuple(f"int{i}" for i in range(8, 257, 8))] +EvmUintType = Literal[tuple(f"uint{i}" for i in range(8, 257, 8))] class _DeferredStrategyRepr(DeferredStrategy): def __init__(self, fn: Callable, repr_target: str) -> None: From d9fb8416730e8cd040c0594ddfd50c3d817c7c4e Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Thu, 30 May 2024 14:50:22 -0400 Subject: [PATCH 10/51] fix: revert genexp and move constants to bottom --- brownie/test/strategies.py | 72 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/brownie/test/strategies.py b/brownie/test/strategies.py index df893b6ef..eef4ca654 100644 --- a/brownie/test/strategies.py +++ b/brownie/test/strategies.py @@ -15,8 +15,6 @@ ArrayLengthType = Union[int, list, None] NumberType = Union[float, int, None] -EvmIntType = Literal[tuple(f"int{i}" for i in range(8, 257, 8))] -EvmUintType = Literal[tuple(f"uint{i}" for i in range(8, 257, 8))] class _DeferredStrategyRepr(DeferredStrategy): def __init__(self, fn: Callable, repr_target: str) -> None: @@ -183,3 +181,73 @@ def strategy(type_str: str, **kwargs: Any) -> SearchStrategy: return _bytes_strategy(abi_type, **kwargs) raise ValueError(f"No strategy available for type: {type_str}") + +EvmIntType = Literal[ + "int8", + "int16", + "int24", + "int32", + "int40", + "int48", + "int56", + "int64", + "int72", + "int80", + "int88", + "int96", + "int104", + "int112", + "int120", + "int128", + "int136", + "int144", + "int152", + "int160", + "int168", + "int176", + "int184", + "int192", + "int200", + "int208", + "int216", + "int224", + "int232", + "int240", + "int248", + "int256", +] + +EvmUintType = Literal[ + "uint8", + "uint16", + "uint24", + "uint32", + "uint40", + "uint48", + "uint56", + "uint64", + "uint72", + "uint80", + "uint88", + "uint96", + "uint104", + "uint112", + "uint120", + "uint128", + "uint136", + "uint144", + "uint152", + "uint160", + "uint168", + "uint176", + "uint184", + "uint192", + "uint200", + "uint208", + "uint216", + "uint224", + "uint232", + "uint240", + "uint248", + "uint256", +] From a8345efd0d71aa1eb42db96eb5fd6a244a41d2fa Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Thu, 30 May 2024 15:02:47 -0400 Subject: [PATCH 11/51] fix: move constants back to top --- brownie/test/strategies.py | 140 ++++++++++++++++++------------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/brownie/test/strategies.py b/brownie/test/strategies.py index eef4ca654..7340b91df 100644 --- a/brownie/test/strategies.py +++ b/brownie/test/strategies.py @@ -16,6 +16,76 @@ ArrayLengthType = Union[int, list, None] NumberType = Union[float, int, None] +EvmIntType = Literal[ + "int8", + "int16", + "int24", + "int32", + "int40", + "int48", + "int56", + "int64", + "int72", + "int80", + "int88", + "int96", + "int104", + "int112", + "int120", + "int128", + "int136", + "int144", + "int152", + "int160", + "int168", + "int176", + "int184", + "int192", + "int200", + "int208", + "int216", + "int224", + "int232", + "int240", + "int248", + "int256", +] + +EvmUintType = Literal[ + "uint8", + "uint16", + "uint24", + "uint32", + "uint40", + "uint48", + "uint56", + "uint64", + "uint72", + "uint80", + "uint88", + "uint96", + "uint104", + "uint112", + "uint120", + "uint128", + "uint136", + "uint144", + "uint152", + "uint160", + "uint168", + "uint176", + "uint184", + "uint192", + "uint200", + "uint208", + "uint216", + "uint224", + "uint232", + "uint240", + "uint248", + "uint256", +] + class _DeferredStrategyRepr(DeferredStrategy): def __init__(self, fn: Callable, repr_target: str) -> None: super().__init__(fn) @@ -181,73 +251,3 @@ def strategy(type_str: str, **kwargs: Any) -> SearchStrategy: return _bytes_strategy(abi_type, **kwargs) raise ValueError(f"No strategy available for type: {type_str}") - -EvmIntType = Literal[ - "int8", - "int16", - "int24", - "int32", - "int40", - "int48", - "int56", - "int64", - "int72", - "int80", - "int88", - "int96", - "int104", - "int112", - "int120", - "int128", - "int136", - "int144", - "int152", - "int160", - "int168", - "int176", - "int184", - "int192", - "int200", - "int208", - "int216", - "int224", - "int232", - "int240", - "int248", - "int256", -] - -EvmUintType = Literal[ - "uint8", - "uint16", - "uint24", - "uint32", - "uint40", - "uint48", - "uint56", - "uint64", - "uint72", - "uint80", - "uint88", - "uint96", - "uint104", - "uint112", - "uint120", - "uint128", - "uint136", - "uint144", - "uint152", - "uint160", - "uint168", - "uint176", - "uint184", - "uint192", - "uint200", - "uint208", - "uint216", - "uint224", - "uint232", - "uint240", - "uint248", - "uint256", -] From 31c597a5b40013e6f75bcb4e854d97b3483e5d86 Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sun, 2 Jun 2024 22:10:58 +0000 Subject: [PATCH 12/51] chore: black . --- brownie/test/strategies.py | 86 +++++++++++++++++++++----------------- 1 file changed, 48 insertions(+), 38 deletions(-) diff --git a/brownie/test/strategies.py b/brownie/test/strategies.py index 7340b91df..3c2a59619 100644 --- a/brownie/test/strategies.py +++ b/brownie/test/strategies.py @@ -18,52 +18,52 @@ EvmIntType = Literal[ "int8", - "int16", - "int24", - "int32", - "int40", - "int48", - "int56", - "int64", - "int72", - "int80", - "int88", - "int96", - "int104", - "int112", - "int120", - "int128", - "int136", - "int144", - "int152", - "int160", - "int168", - "int176", - "int184", - "int192", - "int200", - "int208", - "int216", - "int224", - "int232", - "int240", - "int248", + "int16", + "int24", + "int32", + "int40", + "int48", + "int56", + "int64", + "int72", + "int80", + "int88", + "int96", + "int104", + "int112", + "int120", + "int128", + "int136", + "int144", + "int152", + "int160", + "int168", + "int176", + "int184", + "int192", + "int200", + "int208", + "int216", + "int224", + "int232", + "int240", + "int248", "int256", ] EvmUintType = Literal[ "uint8", "uint16", - "uint24", - "uint32", - "uint40", - "uint48", - "uint56", + "uint24", + "uint32", + "uint40", + "uint48", + "uint56", "uint64", "uint72", "uint80", "uint88", - "uint96", + "uint96", "uint104", "uint112", "uint120", @@ -74,7 +74,7 @@ "uint160", "uint168", "uint176", - "uint184", + "uint184", "uint192", "uint200", "uint208", @@ -86,6 +86,7 @@ "uint256", ] + class _DeferredStrategyRepr(DeferredStrategy): def __init__(self, fn: Callable, repr_target: str) -> None: super().__init__(fn) @@ -221,12 +222,21 @@ def _contract_deferred(name): return _DeferredStrategyRepr(lambda: _contract_deferred(contract_name), contract_name) + @overload def strategy(type_str: Literal["address"], length: Optional[int] = None, include: list = []): ... + + @overload -def strategy(type_str: Union[EvmIntType, EvmUintType], min_value: Optional[int] = None, max_value: Optional[int] = None): +def strategy( + type_str: Union[EvmIntType, EvmUintType], + min_value: Optional[int] = None, + max_value: Optional[int] = None, +): ... + + def strategy(type_str: str, **kwargs: Any) -> SearchStrategy: type_str = TYPE_STR_TRANSLATIONS.get(type_str, type_str) if type_str == "fixed168x10": From 1821a80932cb1ed1becce1bed9d7c384ca047b31 Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Tue, 4 Jun 2024 11:32:08 +0000 Subject: [PATCH 13/51] fix: tox -e lint --- brownie/test/strategies.py | 10 ++++++---- setup.cfg | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/brownie/test/strategies.py b/brownie/test/strategies.py index 3c2a59619..bb089e566 100644 --- a/brownie/test/strategies.py +++ b/brownie/test/strategies.py @@ -224,8 +224,11 @@ def _contract_deferred(name): @overload -def strategy(type_str: Literal["address"], length: Optional[int] = None, include: list = []): - ... +def strategy( + type_str: Literal["address"], + length: Optional[int] = None, + include: list = [], +) -> SearchStrategy: ... @overload @@ -233,8 +236,7 @@ def strategy( type_str: Union[EvmIntType, EvmUintType], min_value: Optional[int] = None, max_value: Optional[int] = None, -): - ... +) -> SearchStrategy: ... def strategy(type_str: str, **kwargs: Any) -> SearchStrategy: diff --git a/setup.cfg b/setup.cfg index 6fed16208..7d815cafb 100644 --- a/setup.cfg +++ b/setup.cfg @@ -8,7 +8,7 @@ current_version = 1.20.5 [flake8] exclude = tests/data/* max-line-length = 100 -ignore = E203,W503 +ignore = E203,E704,W503 [tool:isort] force_grid_wrap = 0 From 0823a8b9dbfe1971a416a8e24262554bbde4645b Mon Sep 17 00:00:00 2001 From: Ben Hauser Date: Sat, 22 Jun 2024 15:24:56 +0000 Subject: [PATCH 14/51] fix: await tx confirmation by watching nonce --- brownie/network/transaction.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/brownie/network/transaction.py b/brownie/network/transaction.py index 138402fa1..4175378bc 100644 --- a/brownie/network/transaction.py +++ b/brownie/network/transaction.py @@ -405,17 +405,22 @@ def wait(self, required_confs: int) -> None: print(f"This transaction already has {self.confirmations} confirmations.") return + if self.nonce is not None: + # if we know the transaction nonce, it's more efficient to watch the tx count + # this (i hope) also fixes a longstanding bug that sometimes gave an incorrect + # "tx dropped without known replacement" error due to a race condition + while web3.eth.get_transaction_count(str(self.sender)) <= self.nonce: + time.sleep(1) + while True: try: tx: Dict = web3.eth.get_transaction(self.txid) break except TransactionNotFound: if self.nonce is not None: - sender_nonce = web3.eth.get_transaction_count(str(self.sender)) - if sender_nonce > self.nonce: - self.status = Status(-2) - self._confirmed.set() - return + self.status = Status(-2) + self._confirmed.set() + return time.sleep(1) self._await_confirmation(tx["blockNumber"], required_confs) From 9d387b4a16c36763df91468a935476c7d090e578 Mon Sep 17 00:00:00 2001 From: Ben Hauser Date: Sat, 22 Jun 2024 15:53:16 +0000 Subject: [PATCH 15/51] release: update changelog, bump version to v1.20.6 --- CHANGELOG.md | 8 ++++++++ brownie/_config.py | 2 +- setup.cfg | 2 +- setup.py | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 824351381..3d1a53af0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://github.com/eth-brownie/brownie) +## [1.20.6](https://github.com/eth-brownie/brownie/tree/v1.20.6) - 2024-06-22 +### Added +- `include` kwarg for address strategy, type-dependent strategy overloads ([#1780](https://github.com/eth-brownie/brownie/pull/1780)) + +### Fixed +- ds-note decoding ([#1781](https://github.com/eth-brownie/brownie/pull/1781)) +- "Dropped without known replacement" tx race condition ([#1782](https://github.com/eth-brownie/brownie/pull/1782)) + ## [1.20.5](https://github.com/eth-brownie/brownie/tree/v1.20.5) - 2024-05-22 ### Fixed - Handle missing `blockNumber` while awaiting confirmation ([#1774](https://github.com/eth-brownie/brownie/pull/1774)) diff --git a/brownie/_config.py b/brownie/_config.py index 2159a892e..2b3ebe6a9 100644 --- a/brownie/_config.py +++ b/brownie/_config.py @@ -19,7 +19,7 @@ from brownie._expansion import expand_posix_vars from brownie._singleton import _Singleton -__version__ = "1.20.5" +__version__ = "1.20.6" BROWNIE_FOLDER = Path(__file__).parent DATA_FOLDER = Path.home().joinpath(".brownie") diff --git a/setup.cfg b/setup.cfg index 7d815cafb..149409482 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 1.20.5 +current_version = 1.20.6 [bumpversion:file:setup.py] diff --git a/setup.py b/setup.py index 5ffa3870b..3d598d6b0 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ setup( name="eth-brownie", packages=find_packages(), - version="1.20.5", # don't change this manually, use bumpversion instead + version="1.20.6", # don't change this manually, use bumpversion instead license="MIT", description="A Python framework for Ethereum smart contract deployment, testing and interaction.", # noqa: E501 long_description=long_description, From 41b116918585752d5546f1b8f6b44178a575cfd0 Mon Sep 17 00:00:00 2001 From: Ben Hauser Date: Wed, 3 Jul 2024 17:54:44 +0000 Subject: [PATCH 16/51] fix: remove tdqm progress bars --- brownie/project/compiler/solidity.py | 2 +- brownie/project/compiler/vyper.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/brownie/project/compiler/solidity.py b/brownie/project/compiler/solidity.py index a1b3d09e3..8fd48449f 100644 --- a/brownie/project/compiler/solidity.py +++ b/brownie/project/compiler/solidity.py @@ -93,7 +93,7 @@ def set_solc_version(version: Union[str, Version]) -> str: def install_solc(*versions: Union[Version, str]) -> None: """Installs solc versions.""" for version in versions: - solcx.install_solc(version, show_progress=True) + solcx.install_solc(version, show_progress=False) def get_abi(contract_source: str, allow_paths: Optional[str] = None) -> Dict: diff --git a/brownie/project/compiler/vyper.py b/brownie/project/compiler/vyper.py index 3448f6ee4..1dafedfe2 100644 --- a/brownie/project/compiler/vyper.py +++ b/brownie/project/compiler/vyper.py @@ -99,7 +99,7 @@ def _get_vyper_version_list() -> Tuple[List, List]: def install_vyper(*versions: str) -> None: """Installs vyper versions.""" for version in versions: - vvm.install_vyper(version, show_progress=True) + vvm.install_vyper(version, show_progress=False) def find_vyper_versions( From 353440ac3ca440584292ed40631ee5d322231fb1 Mon Sep 17 00:00:00 2001 From: Ben Hauser Date: Wed, 3 Jul 2024 17:42:36 +0000 Subject: [PATCH 17/51] fix: do not replace full contract artifacts with abi-only --- brownie/network/state.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/brownie/network/state.py b/brownie/network/state.py index e73f8b0a4..fde7951a8 100644 --- a/brownie/network/state.py +++ b/brownie/network/state.py @@ -632,6 +632,12 @@ def _add_deployment(contract: Any, alias: Optional[str] = None) -> None: f"(address UNIQUE, alias UNIQUE, paths, {', '.join(DEPLOYMENT_KEYS)})" ) + if "compiler" not in contract._build: + # do not replace full contract artifacts with ABI-only ones + row = cur.fetchone(f"SELECT compiler FROM {name} WHERE address=?", (address,)) + if row and row[0]: + return + all_sources = {} for key, path in contract._build.get("allSourcePaths", {}).items(): source = contract._sources.get(path) From 690da0c7c6dfb71a984ccee1acfa805f2a5e3547 Mon Sep 17 00:00:00 2001 From: Ben Hauser Date: Wed, 3 Jul 2024 17:43:17 +0000 Subject: [PATCH 18/51] fix: use cached deployedBytecode where possible --- brownie/network/contract.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/brownie/network/contract.py b/brownie/network/contract.py index bc27021b6..c6f996b72 100644 --- a/brownie/network/contract.py +++ b/brownie/network/contract.py @@ -708,7 +708,9 @@ def __init__( self, address: str, owner: Optional[AccountsType] = None, tx: TransactionReceiptType = None ) -> None: address = _resolve_address(address) - self.bytecode = web3.eth.get_code(address).hex()[2:] + self.bytecode = ( + self._build.get("deployedBytecode", None) or web3.eth.get_code(address).hex()[2:] + ) if not self.bytecode: raise ContractNotFound(f"No contract deployed at {address}") self._owner = owner @@ -948,7 +950,13 @@ def from_abi( will be performed using this account. """ address = _resolve_address(address) - build = {"abi": abi, "address": address, "contractName": name, "type": "contract"} + build = { + "abi": abi, + "address": address, + "contractName": name, + "type": "contract", + "deployedBytecode": web3.eth.get_code(address).hex()[2:], + } self = cls.__new__(cls) _ContractBase.__init__(self, None, build, {}) # type: ignore From 0e3dddf2fdac8366d71d3e40737ae75114ff60a9 Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 00:42:36 +0000 Subject: [PATCH 19/51] fix: compatability issue with vvm 0.2.0 --- brownie/project/compiler/utils.py | 4 ++++ brownie/project/compiler/vyper.py | 20 +++++++++++++++++--- requirements.in | 4 ++-- requirements.txt | 13 +++++++++---- 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/brownie/project/compiler/utils.py b/brownie/project/compiler/utils.py index 7c0627094..70e89f5c3 100644 --- a/brownie/project/compiler/utils.py +++ b/brownie/project/compiler/utils.py @@ -8,6 +8,10 @@ def expand_source_map(source_map_str: str) -> List: # Expands the compressed sourceMap supplied by solc into a list of lists + + if not isinstance(source_map_str, str): + raise TypeError(source_map_str) from None + source_map: List = [_expand_row(i) if i else None for i in source_map_str.split(";")] for i, value in enumerate(source_map[1:], 1): if value is None: diff --git a/brownie/project/compiler/vyper.py b/brownie/project/compiler/vyper.py index 1dafedfe2..9e2f3b59c 100644 --- a/brownie/project/compiler/vyper.py +++ b/brownie/project/compiler/vyper.py @@ -7,6 +7,7 @@ import vvm import vyper +from packaging.version import Version as PVersion from requests.exceptions import ConnectionError from semantic_version import Version from vyper.cli import vyper_json @@ -46,6 +47,8 @@ def set_vyper_version(version: Union[str, Version]) -> str: if isinstance(version, str): version = Version(version) if version != Version(vyper.__version__): + # NOTE: vvm uses packaging.version.Version which is not compatible with semantic_version.Version so we first must cast it as a string + version = str(version) try: vvm.set_vyper_version(version, silent=True) except vvm.exceptions.VyperNotInstalled: @@ -82,13 +85,13 @@ def get_abi(contract_source: str, name: str) -> Dict: def _get_vyper_version_list() -> Tuple[List, List]: global AVAILABLE_VYPER_VERSIONS - installed_versions = vvm.get_installed_vyper_versions() + installed_versions = _convert_to_semver(vvm.get_installed_vyper_versions()) lib_version = Version(vyper.__version__) if lib_version not in installed_versions: installed_versions.append(lib_version) if AVAILABLE_VYPER_VERSIONS is None: try: - AVAILABLE_VYPER_VERSIONS = vvm.get_installable_vyper_versions() + AVAILABLE_VYPER_VERSIONS = _convert_to_semver(vvm.get_installable_vyper_versions()) except ConnectionError: if not installed_versions: raise ConnectionError("Vyper not installed and cannot connect to GitHub") @@ -237,11 +240,13 @@ def compile_from_input_json( outputs.remove("devdoc") if version == Version(vyper.__version__): try: - return vyper_json.compile_json(input_json, root_path=allow_paths) + return vyper_json.compile_json(input_json) except VyperException as exc: raise exc.with_traceback(None) else: try: + # NOTE: vvm uses packaging.version.Version which is not compatible with semantic_version.Version so we first must cast it as a string + version = str(version) return vvm.compile_standard(input_json, base_path=allow_paths, vyper_version=version) except vvm.exceptions.VyperError as exc: raise CompilerError(exc, "vyper") @@ -449,3 +454,12 @@ def _get_statement_nodes(ast_json: List) -> List: else: stmt_nodes.append(node) return stmt_nodes + + +def _convert_to_semver(versions: List[PVersion]) -> List[Version]: + """ + Converts a list of packaging.version.Version objects to a list of semantic_version.Version objects. + vvm 0.2.0 switched to packaging.version but we are not ready to migrate brownie off of semantic-version. + This function serves as a stopgap. + """ + return [Version(major=version.major, minor=version.minor, patch=version.micro, prerelease=''.join(str(x) for x in version.pre)) for version in versions] \ No newline at end of file diff --git a/requirements.in b/requirements.in index 56d07b964..405ae2cd6 100644 --- a/requirements.in +++ b/requirements.in @@ -23,7 +23,7 @@ requests>=2.25.0,<3 rlp semantic-version<3 tqdm<5 -vvm==0.1.0 # 0.2.0 switches from semantic-version to packaging.version and things break -vyper>=0.3.8,<0.4 +vvm==0.2.1 +vyper>=0.4.0,<0.5 web3>=6,<7 wrapt>=1.12.1,<2 diff --git a/requirements.txt b/requirements.txt index 9758d4e63..410e36a15 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.11 +# This file is autogenerated by pip-compile with Python 3.10 # by the following command: # # pip-compile requirements.in @@ -10,6 +10,8 @@ aiosignal==1.3.1 # via aiohttp asttokens==2.4.1 # via vyper +async-timeout==4.0.3 + # via aiohttp attrs==23.2.0 # via # aiohttp @@ -125,6 +127,7 @@ packaging==23.2 # via # black # pytest + # vvm # vyper parsimonious==0.9.0 # via eth-abi @@ -200,7 +203,6 @@ semantic-version==2.10.0 # via # -r requirements.in # py-solc-x - # vvm six==1.16.0 # via # asttokens @@ -209,20 +211,23 @@ sortedcontainers==2.4.0 # via hypothesis toml==0.10.2 # via pytest +tomli==2.0.1 + # via black toolz==0.12.1 # via cytoolz tqdm==4.66.2 # via -r requirements.in typing-extensions==4.9.0 # via + # black # eth-rlp # eth-typing # web3 urllib3==2.2.1 # via requests -vvm==0.1.0 +vvm==0.2.1 # via -r requirements.in -vyper==0.3.10 +vyper==0.4.0 # via -r requirements.in wcwidth==0.2.13 # via prompt-toolkit From 9e2d8b48d6b5792618f5e8074300687f6372b79d Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 00:46:46 +0000 Subject: [PATCH 20/51] fix: None not iterable --- brownie/project/compiler/vyper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brownie/project/compiler/vyper.py b/brownie/project/compiler/vyper.py index 9e2f3b59c..3163290b4 100644 --- a/brownie/project/compiler/vyper.py +++ b/brownie/project/compiler/vyper.py @@ -462,4 +462,4 @@ def _convert_to_semver(versions: List[PVersion]) -> List[Version]: vvm 0.2.0 switched to packaging.version but we are not ready to migrate brownie off of semantic-version. This function serves as a stopgap. """ - return [Version(major=version.major, minor=version.minor, patch=version.micro, prerelease=''.join(str(x) for x in version.pre)) for version in versions] \ No newline at end of file + return [Version(major=version.major, minor=version.minor, patch=version.micro, prerelease=''.join(str(x) for x in version.pre) if version.pre else None) for version in versions] \ No newline at end of file From c6eed94ebb3c8acfadda0902a6d74da55c90d35c Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 00:50:16 +0000 Subject: [PATCH 21/51] fix: TypeError --- brownie/project/compiler/vyper.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/brownie/project/compiler/vyper.py b/brownie/project/compiler/vyper.py index 3163290b4..a30f89b5e 100644 --- a/brownie/project/compiler/vyper.py +++ b/brownie/project/compiler/vyper.py @@ -48,12 +48,12 @@ def set_vyper_version(version: Union[str, Version]) -> str: version = Version(version) if version != Version(vyper.__version__): # NOTE: vvm uses packaging.version.Version which is not compatible with semantic_version.Version so we first must cast it as a string - version = str(version) + version_str = str(version) try: - vvm.set_vyper_version(version, silent=True) + vvm.set_vyper_version(version_str, silent=True) except vvm.exceptions.VyperNotInstalled: install_vyper(version) - vvm.set_vyper_version(version, silent=True) + vvm.set_vyper_version(version_str, silent=True) _active_version = version return str(_active_version) From 7f58e2fcd754a65e89a003e04cad9a0558bddef0 Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 00:55:51 +0000 Subject: [PATCH 22/51] fix: debug source_map_str not being string --- brownie/project/compiler/vyper.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/brownie/project/compiler/vyper.py b/brownie/project/compiler/vyper.py index a30f89b5e..af6f6a681 100644 --- a/brownie/project/compiler/vyper.py +++ b/brownie/project/compiler/vyper.py @@ -262,8 +262,12 @@ def _get_unique_build_json( else: ast = ast_json + source_map = output_evm["deployedBytecode"]["sourceMap"] + if not isinstance(source_map, str): + raise TypeError(source_map) + pc_map, statement_map, branch_map = _generate_coverage_data( - output_evm["deployedBytecode"]["sourceMap"], + source_map, output_evm["deployedBytecode"]["opcodes"], contract_name, ast, From d28b3b09d30c6a86e9d3688365f9ceebbbfc9e01 Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 01:03:56 +0000 Subject: [PATCH 23/51] chore: add exc detail --- brownie/project/compiler/vyper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brownie/project/compiler/vyper.py b/brownie/project/compiler/vyper.py index af6f6a681..6179e8ecc 100644 --- a/brownie/project/compiler/vyper.py +++ b/brownie/project/compiler/vyper.py @@ -264,7 +264,7 @@ def _get_unique_build_json( source_map = output_evm["deployedBytecode"]["sourceMap"] if not isinstance(source_map, str): - raise TypeError(source_map) + raise TypeError(source_map.keys(), source_map) pc_map, statement_map, branch_map = _generate_coverage_data( source_map, From 3ad567b2aa91bb5571d6971465b54cef5815b7c8 Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 01:09:41 +0000 Subject: [PATCH 24/51] chore: add exc detail --- brownie/project/compiler/utils.py | 2 ++ brownie/project/compiler/vyper.py | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/brownie/project/compiler/utils.py b/brownie/project/compiler/utils.py index 70e89f5c3..21be6ecba 100644 --- a/brownie/project/compiler/utils.py +++ b/brownie/project/compiler/utils.py @@ -10,6 +10,8 @@ def expand_source_map(source_map_str: str) -> List: # Expands the compressed sourceMap supplied by solc into a list of lists if not isinstance(source_map_str, str): + # NOTE: why do we need this? + source_map_str = source_map_str["ps_pos_map_compressed"] raise TypeError(source_map_str) from None source_map: List = [_expand_row(i) if i else None for i in source_map_str.split(";")] diff --git a/brownie/project/compiler/vyper.py b/brownie/project/compiler/vyper.py index 6179e8ecc..3a94012cb 100644 --- a/brownie/project/compiler/vyper.py +++ b/brownie/project/compiler/vyper.py @@ -263,8 +263,8 @@ def _get_unique_build_json( ast = ast_json source_map = output_evm["deployedBytecode"]["sourceMap"] - if not isinstance(source_map, str): - raise TypeError(source_map.keys(), source_map) + #if not isinstance(source_map, str): + # raise TypeError(source_map.keys(), source_map) pc_map, statement_map, branch_map = _generate_coverage_data( source_map, From 70423777121004c6894f13ca9133c384f24e40d5 Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 01:10:54 +0000 Subject: [PATCH 25/51] fix: typo --- brownie/project/compiler/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brownie/project/compiler/utils.py b/brownie/project/compiler/utils.py index 21be6ecba..82b2ee44e 100644 --- a/brownie/project/compiler/utils.py +++ b/brownie/project/compiler/utils.py @@ -11,7 +11,7 @@ def expand_source_map(source_map_str: str) -> List: if not isinstance(source_map_str, str): # NOTE: why do we need this? - source_map_str = source_map_str["ps_pos_map_compressed"] + source_map_str = source_map_str["pc_pos_map_compressed"] raise TypeError(source_map_str) from None source_map: List = [_expand_row(i) if i else None for i in source_map_str.split(";")] From 804a2f383b1b40277e99f53252daaf715b46d7de Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 01:12:02 +0000 Subject: [PATCH 26/51] fix: typo --- brownie/project/compiler/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brownie/project/compiler/utils.py b/brownie/project/compiler/utils.py index 82b2ee44e..5673f2bb8 100644 --- a/brownie/project/compiler/utils.py +++ b/brownie/project/compiler/utils.py @@ -12,7 +12,7 @@ def expand_source_map(source_map_str: str) -> List: if not isinstance(source_map_str, str): # NOTE: why do we need this? source_map_str = source_map_str["pc_pos_map_compressed"] - raise TypeError(source_map_str) from None + #raise TypeError(source_map_str) from None source_map: List = [_expand_row(i) if i else None for i in source_map_str.split(";")] for i, value in enumerate(source_map[1:], 1): From 8b09824df47c6b03c46d0d59e503c8e6d8934980 Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 01:14:33 +0000 Subject: [PATCH 27/51] fix: KeyError --- brownie/project/compiler/vyper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brownie/project/compiler/vyper.py b/brownie/project/compiler/vyper.py index 3a94012cb..794b1afc0 100644 --- a/brownie/project/compiler/vyper.py +++ b/brownie/project/compiler/vyper.py @@ -406,7 +406,7 @@ def _generate_coverage_data( if node["ast_type"] in ("Assert", "If") or ( node["ast_type"] == "Expr" - and node["value"]["func"].get("id", None) == "assert_modifiable" + and node["value"].get("func", {}).get("id", None) == "assert_modifiable" ): # branch coverage pc_list[-1]["branch"] = count From 35c2741e63dbab6e66d2e5c60906598088b8544d Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 16:29:12 +0000 Subject: [PATCH 28/51] chore: black --- brownie/project/compiler/utils.py | 5 ++--- brownie/project/compiler/vyper.py | 16 ++++++++++------ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/brownie/project/compiler/utils.py b/brownie/project/compiler/utils.py index 5673f2bb8..784071239 100644 --- a/brownie/project/compiler/utils.py +++ b/brownie/project/compiler/utils.py @@ -8,12 +8,11 @@ def expand_source_map(source_map_str: str) -> List: # Expands the compressed sourceMap supplied by solc into a list of lists - + if not isinstance(source_map_str, str): # NOTE: why do we need this? source_map_str = source_map_str["pc_pos_map_compressed"] - #raise TypeError(source_map_str) from None - + source_map: List = [_expand_row(i) if i else None for i in source_map_str.split(";")] for i, value in enumerate(source_map[1:], 1): if value is None: diff --git a/brownie/project/compiler/vyper.py b/brownie/project/compiler/vyper.py index 794b1afc0..4d0cccd9a 100644 --- a/brownie/project/compiler/vyper.py +++ b/brownie/project/compiler/vyper.py @@ -262,12 +262,8 @@ def _get_unique_build_json( else: ast = ast_json - source_map = output_evm["deployedBytecode"]["sourceMap"] - #if not isinstance(source_map, str): - # raise TypeError(source_map.keys(), source_map) - pc_map, statement_map, branch_map = _generate_coverage_data( - source_map, + output_evm["deployedBytecode"]["sourceMap"], output_evm["deployedBytecode"]["opcodes"], contract_name, ast, @@ -466,4 +462,12 @@ def _convert_to_semver(versions: List[PVersion]) -> List[Version]: vvm 0.2.0 switched to packaging.version but we are not ready to migrate brownie off of semantic-version. This function serves as a stopgap. """ - return [Version(major=version.major, minor=version.minor, patch=version.micro, prerelease=''.join(str(x) for x in version.pre) if version.pre else None) for version in versions] \ No newline at end of file + return [ + Version( + major=version.major, + minor=version.minor, + patch=version.micro, + prerelease="".join(str(x) for x in version.pre) if version.pre else None, + ) + for version in versions + ] From 674dc8f7cdb746bba627466d6ff4f286b493db8e Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 16:33:37 +0000 Subject: [PATCH 29/51] chore: flake8 --- brownie/project/compiler/vyper.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/brownie/project/compiler/vyper.py b/brownie/project/compiler/vyper.py index 4d0cccd9a..61af3eaa6 100644 --- a/brownie/project/compiler/vyper.py +++ b/brownie/project/compiler/vyper.py @@ -47,7 +47,8 @@ def set_vyper_version(version: Union[str, Version]) -> str: if isinstance(version, str): version = Version(version) if version != Version(vyper.__version__): - # NOTE: vvm uses packaging.version.Version which is not compatible with semantic_version.Version so we first must cast it as a string + # NOTE: vvm uses `packaging.version.Version` which is not compatible with + # `semantic_version.Version` so we first must cast it as a string version_str = str(version) try: vvm.set_vyper_version(version_str, silent=True) @@ -245,7 +246,8 @@ def compile_from_input_json( raise exc.with_traceback(None) else: try: - # NOTE: vvm uses packaging.version.Version which is not compatible with semantic_version.Version so we first must cast it as a string + # NOTE: vvm uses `packaging.version.Version` which is not compatible with + # `semantic_version.Version` so we first must cast it as a string version = str(version) return vvm.compile_standard(input_json, base_path=allow_paths, vyper_version=version) except vvm.exceptions.VyperError as exc: @@ -458,8 +460,12 @@ def _get_statement_nodes(ast_json: List) -> List: def _convert_to_semver(versions: List[PVersion]) -> List[Version]: """ - Converts a list of packaging.version.Version objects to a list of semantic_version.Version objects. - vvm 0.2.0 switched to packaging.version but we are not ready to migrate brownie off of semantic-version. + Converts a list of `packaging.version.Version` objects to a list of + `semantic_version.Version` objects. + + vvm 0.2.0 switched to packaging.version but we are not ready to + migrate brownie off of semantic-version. + This function serves as a stopgap. """ return [ From e05e53fada8e5cb9a209478eda23ab632b7f6562 Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 16:35:42 +0000 Subject: [PATCH 30/51] chore: black --- brownie/project/compiler/vyper.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/brownie/project/compiler/vyper.py b/brownie/project/compiler/vyper.py index 61af3eaa6..acd754904 100644 --- a/brownie/project/compiler/vyper.py +++ b/brownie/project/compiler/vyper.py @@ -47,7 +47,7 @@ def set_vyper_version(version: Union[str, Version]) -> str: if isinstance(version, str): version = Version(version) if version != Version(vyper.__version__): - # NOTE: vvm uses `packaging.version.Version` which is not compatible with + # NOTE: vvm uses `packaging.version.Version` which is not compatible with # `semantic_version.Version` so we first must cast it as a string version_str = str(version) try: @@ -246,7 +246,7 @@ def compile_from_input_json( raise exc.with_traceback(None) else: try: - # NOTE: vvm uses `packaging.version.Version` which is not compatible with + # NOTE: vvm uses `packaging.version.Version` which is not compatible with # `semantic_version.Version` so we first must cast it as a string version = str(version) return vvm.compile_standard(input_json, base_path=allow_paths, vyper_version=version) From b8cd61ed35520f84ba3b3242af7bd4674c162ed0 Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 22:14:05 +0000 Subject: [PATCH 31/51] feat(gh): limit workflow concurrency --- .github/workflows/core-ganache-3.10.yaml | 5 +++++ .github/workflows/core-ganache-3.11.yaml | 5 +++++ .github/workflows/core-ganache-3.12.yaml | 5 +++++ .github/workflows/evm.yaml | 5 +++++ .github/workflows/functionality.yaml | 5 +++++ .github/workflows/lint.yaml | 5 +++++ 6 files changed, 30 insertions(+) diff --git a/.github/workflows/core-ganache-3.10.yaml b/.github/workflows/core-ganache-3.10.yaml index 8073c62cc..d4164c4f2 100644 --- a/.github/workflows/core-ganache-3.10.yaml +++ b/.github/workflows/core-ganache-3.10.yaml @@ -1,6 +1,11 @@ name: Core Ganache (py3.10) on: ["push", "pull_request"] +# This limits the workflow to 1 active run at any given time for a specific branch +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + env: ETHERSCAN_TOKEN: 9MKURTHE8FNA9NRUUJBHMUEVY6IQ5K1EGY GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/core-ganache-3.11.yaml b/.github/workflows/core-ganache-3.11.yaml index bb8775fe5..2536cb39b 100644 --- a/.github/workflows/core-ganache-3.11.yaml +++ b/.github/workflows/core-ganache-3.11.yaml @@ -1,6 +1,11 @@ name: Core Ganache (py3.11) on: ["push", "pull_request"] +# This limits the workflow to 1 active run at any given time for a specific branch +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + env: ETHERSCAN_TOKEN: 9MKURTHE8FNA9NRUUJBHMUEVY6IQ5K1EGY GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/core-ganache-3.12.yaml b/.github/workflows/core-ganache-3.12.yaml index 158fac1fa..60a3b04d9 100644 --- a/.github/workflows/core-ganache-3.12.yaml +++ b/.github/workflows/core-ganache-3.12.yaml @@ -1,6 +1,11 @@ name: Core Ganache (py3.12) on: ["push", "pull_request"] +# This limits the workflow to 1 active run at any given time for a specific branch +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + env: ETHERSCAN_TOKEN: 9MKURTHE8FNA9NRUUJBHMUEVY6IQ5K1EGY GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/evm.yaml b/.github/workflows/evm.yaml index e364b3f21..f5ed5071e 100644 --- a/.github/workflows/evm.yaml +++ b/.github/workflows/evm.yaml @@ -2,6 +2,11 @@ on: ["push", "pull_request"] name: evm tests +# This limits the workflow to 1 active run at any given time for a specific branch +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + env: ETHERSCAN_TOKEN: 9MKURTHE8FNA9NRUUJBHMUEVY6IQ5K1EGY GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/functionality.yaml b/.github/workflows/functionality.yaml index 34ec13af4..1494b6da2 100644 --- a/.github/workflows/functionality.yaml +++ b/.github/workflows/functionality.yaml @@ -2,6 +2,11 @@ on: ["push", "pull_request"] name: functionality +# This limits the workflow to 1 active run at any given time for a specific branch +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + env: ETHERSCAN_TOKEN: 9MKURTHE8FNA9NRUUJBHMUEVY6IQ5K1EGY GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 6a89de0b3..774df0ea8 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -2,6 +2,11 @@ on: ["push", "pull_request"] name: linting +# This limits the workflow to 1 active run at any given time for a specific branch +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + env: ETHERSCAN_TOKEN: 9MKURTHE8FNA9NRUUJBHMUEVY6IQ5K1EGY GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From dc665d1b23eb352578858401f01b6f5cfea7de8c Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Sat, 17 Aug 2024 21:53:43 -0400 Subject: [PATCH 32/51] chore: better comment --- brownie/project/compiler/utils.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/brownie/project/compiler/utils.py b/brownie/project/compiler/utils.py index 784071239..8694d9cd7 100644 --- a/brownie/project/compiler/utils.py +++ b/brownie/project/compiler/utils.py @@ -8,10 +8,12 @@ def expand_source_map(source_map_str: str) -> List: # Expands the compressed sourceMap supplied by solc into a list of lists - - if not isinstance(source_map_str, str): - # NOTE: why do we need this? +' + if isinstance(source_map_str, dict): + # NOTE: vyper >= 0.4 gives us a dict that contains the source map source_map_str = source_map_str["pc_pos_map_compressed"] + if not isinstance(source_map_str, str): + raise TypeError(source_map_str) source_map: List = [_expand_row(i) if i else None for i in source_map_str.split(";")] for i, value in enumerate(source_map[1:], 1): From 326cce6b0fbd8d20cffd2d03e082e855aa923a89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stas=20SU=C8=98COV?= Date: Wed, 23 Oct 2024 18:47:25 +0100 Subject: [PATCH 33/51] typo --- brownie/project/compiler/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brownie/project/compiler/utils.py b/brownie/project/compiler/utils.py index 8694d9cd7..98c947252 100644 --- a/brownie/project/compiler/utils.py +++ b/brownie/project/compiler/utils.py @@ -8,7 +8,7 @@ def expand_source_map(source_map_str: str) -> List: # Expands the compressed sourceMap supplied by solc into a list of lists -' + if isinstance(source_map_str, dict): # NOTE: vyper >= 0.4 gives us a dict that contains the source map source_map_str = source_map_str["pc_pos_map_compressed"] From 910fbee2336421577c07d6f6b7e4702872afada3 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Sat, 9 Nov 2024 14:06:02 -0400 Subject: [PATCH 34/51] chore: add py.typed marker --- setup.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup.py b/setup.py index 3d598d6b0..e79b26cbf 100644 --- a/setup.py +++ b/setup.py @@ -38,6 +38,9 @@ "console_scripts": ["brownie=brownie._cli.__main__:main"], "pytest11": ["pytest-brownie=brownie.test.plugin"], }, + package_data={ + "brownie": ["py.typed"], + }, include_package_data=True, python_requires=">=3.10,<4", classifiers=[ From 6a90de9dd4d2f2ca6c444d9d888659ec3c7c88c3 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Sun, 10 Nov 2024 13:16:57 -0400 Subject: [PATCH 35/51] feat(mypy): add py.typed marker --- brownie/py.typed | 1 + 1 file changed, 1 insertion(+) create mode 100644 brownie/py.typed diff --git a/brownie/py.typed b/brownie/py.typed new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/brownie/py.typed @@ -0,0 +1 @@ + From f4341fbc329fdd960cec879e9be65aa34857c434 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Wed, 4 Dec 2024 04:06:55 -0400 Subject: [PATCH 36/51] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d1a53af0..77f9f5ece 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ This changelog format is based on [Keep a Changelog](https://keepachangelog.com/ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased](https://github.com/eth-brownie/brownie) +### Added +- `py.typed` marker ## [1.20.6](https://github.com/eth-brownie/brownie/tree/v1.20.6) - 2024-06-22 ### Added From 83a4057e999a5829f4848c338ee2002548cda28b Mon Sep 17 00:00:00 2001 From: Ben Hauser Date: Tue, 7 Jan 2025 12:47:13 +0000 Subject: [PATCH 37/51] fix: vvm Version TypeError --- brownie/project/compiler/vyper.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/brownie/project/compiler/vyper.py b/brownie/project/compiler/vyper.py index acd754904..8b93d5933 100644 --- a/brownie/project/compiler/vyper.py +++ b/brownie/project/compiler/vyper.py @@ -77,7 +77,7 @@ def get_abi(contract_source: str, name: str) -> Dict: raise exc.with_traceback(None) else: try: - compiled = vvm.compile_standard(input_json, vyper_version=_active_version) + compiled = vvm.compile_standard(input_json, vyper_version=str(_active_version)) except vvm.exceptions.VyperError as exc: raise CompilerError(exc, "vyper") @@ -103,7 +103,7 @@ def _get_vyper_version_list() -> Tuple[List, List]: def install_vyper(*versions: str) -> None: """Installs vyper versions.""" for version in versions: - vvm.install_vyper(version, show_progress=False) + vvm.install_vyper(str(version), show_progress=False) def find_vyper_versions( @@ -150,7 +150,7 @@ def find_vyper_versions( ) if not version or (install_latest and latest > version): - to_install.add(latest) + to_install.add(str(latest)) elif latest and latest > version: new_versions.add(str(version)) From aa3f8aa5069c6f3b2f8b7e6216ea7a720ba54428 Mon Sep 17 00:00:00 2001 From: Ben Hauser Date: Mon, 6 Jan 2025 22:24:39 +0000 Subject: [PATCH 38/51] release: update changelog, bump version to v1.20.7 --- CHANGELOG.md | 11 ++++++++++- brownie/_config.py | 2 +- setup.cfg | 2 +- setup.py | 2 +- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77f9f5ece..7edf3ce83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,17 @@ This changelog format is based on [Keep a Changelog](https://keepachangelog.com/ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased](https://github.com/eth-brownie/brownie) + +## [1.20.7](https://github.com/eth-brownie/brownie/tree/v1.20.7) - 2025-01-07 ### Added -- `py.typed` marker +- Support for vyper `0.4.0` ([#1793](https://github.com/eth-brownie/brownie/pull/1793)) +- `py.typed` marker ([#1794](https://github.com/eth-brownie/brownie/pull/1794)) + +### Fixed +- Improvements to caching ([#1786](https://github.com/eth-brownie/brownie/pull/1786)) + +### Removed +- `tqdm` progress bars during compiler installation ([#1785](https://github.com/eth-brownie/brownie/pull/1785)) ## [1.20.6](https://github.com/eth-brownie/brownie/tree/v1.20.6) - 2024-06-22 ### Added diff --git a/brownie/_config.py b/brownie/_config.py index 2b3ebe6a9..2e378fccb 100644 --- a/brownie/_config.py +++ b/brownie/_config.py @@ -19,7 +19,7 @@ from brownie._expansion import expand_posix_vars from brownie._singleton import _Singleton -__version__ = "1.20.6" +__version__ = "1.20.7" BROWNIE_FOLDER = Path(__file__).parent DATA_FOLDER = Path.home().joinpath(".brownie") diff --git a/setup.cfg b/setup.cfg index 149409482..28560d976 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 1.20.6 +current_version = 1.20.7 [bumpversion:file:setup.py] diff --git a/setup.py b/setup.py index e79b26cbf..99ef113a1 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ setup( name="eth-brownie", packages=find_packages(), - version="1.20.6", # don't change this manually, use bumpversion instead + version="1.20.7", # don't change this manually, use bumpversion instead license="MIT", description="A Python framework for Ethereum smart contract deployment, testing and interaction.", # noqa: E501 long_description=long_description, From af94724db40e846e49aff977ab14da0de5c4c255 Mon Sep 17 00:00:00 2001 From: Cypher Pepe <125112044+cypherpepe@users.noreply.github.com> Date: Sun, 2 Mar 2025 02:20:04 +0300 Subject: [PATCH 39/51] fix: Broken links (#1803) * fix broken links install.rst * fix broken link CHANGELOG.md --- CHANGELOG.md | 2 +- docs/install.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7edf3ce83..e6859aa55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -126,7 +126,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [1.19.0](https://github.com/eth-brownie/brownie/tree/v1.19.0) - 2022-05-29 ### Added -- Initial support for [Anvil](https://github.com/foundry-rs/foundry/tree/master/anvil), a blazing-fast local testnet node implementation in Rust ([#1541](https://github.com/eth-brownie/brownie/pull/1541)) +- Initial support for [Anvil](https://github.com/foundry-rs/foundry/tree/master/crates/anvil), a blazing-fast local testnet node implementation in Rust ([#1541](https://github.com/eth-brownie/brownie/pull/1541)) - Support configurable initial wallet balance, chain id, and gas limit. ### Fixed diff --git a/docs/install.rst b/docs/install.rst index 8037b3d94..bcba38699 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -114,9 +114,9 @@ If you have updated your brownie version from older versions, hardhat networks w Using Brownie with Anvil ========================== -`Anvil `_ is a blazing-fast local testnet node implementation in Rust. Anvil may be used as an alternative to Ganache within Brownie. +`Anvil `_ is a blazing-fast local testnet node implementation in Rust. Anvil may be used as an alternative to Ganache within Brownie. -To use Anvil with Brownie, you must first `follow their steps to install Anvil `_. +To use Anvil with Brownie, you must first `follow their steps to install Anvil `_. Once installed, include the ``--network anvil`` or ``--network anvil-fork`` flag to run Brownie with Anvil. For example, to launch the console: From a630a7ed25879cb653a880ea20fdad20c565015f Mon Sep 17 00:00:00 2001 From: teenager-ETH Date: Sun, 2 Mar 2025 00:21:29 +0100 Subject: [PATCH 40/51] chore: fix typos (#1804) * typo fix * typo fix --- README.md | 2 +- brownie/project/main.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ba2372975..859192a89 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ To upgrade to the latest version: pipx upgrade eth-brownie ``` -To use lastest master or another branch as version: +To use latest master or another branch as version: ```bash pipx install git+https://github.com/eth-brownie/brownie.git@master ``` diff --git a/brownie/project/main.py b/brownie/project/main.py index d0138b055..a0d0d3b78 100644 --- a/brownie/project/main.py +++ b/brownie/project/main.py @@ -811,7 +811,7 @@ def _install_from_github(package_id: str) -> str: install_path.mkdir(exist_ok=True) install_path = install_path.joinpath(f"{repo}@{version}") if install_path.exists(): - raise FileExistsError("Package is aleady installed") + raise FileExistsError("Package is already installed") headers = REQUEST_HEADERS.copy() headers.update(_maybe_retrieve_github_auth()) From e9611f1a47f0dd5dc3f2528e16563e7f7a65bfd3 Mon Sep 17 00:00:00 2001 From: kilavvy <140459108+kilavvy@users.noreply.github.com> Date: Wed, 19 Mar 2025 18:31:54 +0100 Subject: [PATCH 41/51] fix: typos in documentation files (#1810) * Update api-network.rst * Update api-brownie.rst --- docs/api-brownie.rst | 2 +- docs/api-network.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api-brownie.rst b/docs/api-brownie.rst index 6281d0c5f..db04b0c62 100644 --- a/docs/api-brownie.rst +++ b/docs/api-brownie.rst @@ -41,7 +41,7 @@ Exceptions .. py:exception:: brownie.exceptions.IncompatibleEVMVersion - Raised when attempting to deploy a contract that was compiled to target an EVM version that is imcompatible than the currently active local RPC client. + Raised when attempting to deploy a contract that was compiled to target an EVM version that is incompatible than the currently active local RPC client. .. py:exception:: brownie.exceptions.IncompatibleSolcVersion diff --git a/docs/api-network.rst b/docs/api-network.rst index 802a3e5f1..c6afef8b9 100644 --- a/docs/api-network.rst +++ b/docs/api-network.rst @@ -1642,7 +1642,7 @@ Internal Methods .. py:method:: brownie.network.event._get_topics(abi) - Generates encoded topics from the given ABI, merges them with those already known in ``topics.json``, and returns a dictioary in the form of ``{'Name': "encoded topic hexstring"}``. + Generates encoded topics from the given ABI, merges them with those already known in ``topics.json``, and returns a dictionary in the form of ``{'Name': "encoded topic hexstring"}``. .. code-block:: python From a657dcc9f57616e630dc7bd1d3b3f04b4479acac Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Thu, 20 Mar 2025 05:16:16 -0400 Subject: [PATCH 42/51] feat: pip-compile gh action --- .github/workflows/pip-compile.yaml | 49 ++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 .github/workflows/pip-compile.yaml diff --git a/.github/workflows/pip-compile.yaml b/.github/workflows/pip-compile.yaml new file mode 100644 index 000000000..f8d52f9ab --- /dev/null +++ b/.github/workflows/pip-compile.yaml @@ -0,0 +1,49 @@ +name: Pip Compile + +on: + pull_request: + branches: + - master + paths: + - 'requirements.in' + - 'requirements-windows.in' + - 'requirements-dev.in' + +jobs: + format: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + ref: ${{ github.head_ref }} # Check out the PR branch + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.11' + + - name: Install Pip Tools + run: pip install pip-tools + + - name: Run Pip Compile + run: pip-compile + + - name: Check for changes + id: changes + run: | + if [[ -n $(git status --porcelain) ]]; then + echo "changes_detected=true" >> $GITHUB_ENV + else + echo "changes_detected=false" >> $GITHUB_ENV + fi + + - name: Commit changes + if: env.changes_detected == 'true' + run: | + git config --local user.name "github-actions[bot]" + git config --local user.email "github-actions[bot]@users.noreply.github.com" + git add . + git commit -m "chore: \`pip-compile\`" + git push From b2c4949d1e50852ef4c649d1b7fe6c93b58d423b Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Thu, 20 Mar 2025 11:29:46 -0400 Subject: [PATCH 43/51] feat: implement cchecksum for ~2x faster checksumming (#1796) --- CHANGELOG.md | 2 ++ brownie/convert/datatypes.py | 3 ++- requirements.in | 1 + requirements.txt | 4 ++++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6859aa55..f8de38dbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ This changelog format is based on [Keep a Changelog](https://keepachangelog.com/ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased](https://github.com/eth-brownie/brownie) +### Changed +- replace `eth_utils.to_checksum_address` with `cchecksum.to_checksum_address` for ~2x faster checksumming ([#1796](https://github.com/eth-brownie/brownie/pull/1796)) ## [1.20.7](https://github.com/eth-brownie/brownie/tree/v1.20.7) - 2025-01-07 ### Added diff --git a/brownie/convert/datatypes.py b/brownie/convert/datatypes.py index 3209258a2..202e17d39 100644 --- a/brownie/convert/datatypes.py +++ b/brownie/convert/datatypes.py @@ -9,6 +9,7 @@ except ImportError: DecimalOverrideException = BaseException # regular catch blocks shouldn't catch +import cchecksum import eth_utils from hexbytes import HexBytes @@ -205,7 +206,7 @@ def __new__(cls, value: Union[bytes, str]) -> str: converted_value = HexBytes(value).hex() converted_value = eth_utils.add_0x_prefix(str(converted_value)) # type: ignore try: - converted_value = eth_utils.to_checksum_address(converted_value) + converted_value = cchecksum.to_checksum_address(converted_value) except ValueError: raise ValueError(f"'{value}' is not a valid ETH address") from None return super().__new__(cls, converted_value) # type: ignore diff --git a/requirements.in b/requirements.in index 405ae2cd6..b4fb18cb2 100644 --- a/requirements.in +++ b/requirements.in @@ -1,4 +1,5 @@ black>=20.8b1 +cchecksum>=0.0.3 eip712 eth-abi eth-account diff --git a/requirements.txt b/requirements.txt index 410e36a15..26e114aa2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -25,6 +25,8 @@ black==24.2.0 # via -r requirements.in cbor2==5.6.2 # via vyper +cchecksum==0.0.7 + # via -r requirements.in certifi==2024.2.2 # via requests charset-normalizer==3.3.2 @@ -68,6 +70,7 @@ eth-rlp==1.0.1 # via eth-account eth-typing==3.5.2 # via + # cchecksum # eip712 # eth-abi # eth-keys @@ -76,6 +79,7 @@ eth-typing==3.5.2 eth-utils==2.3.1 # via # -r requirements.in + # cchecksum # eip712 # eth-abi # eth-account From f9388249d563a34643ed43cb3d59c1c58df5fa75 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Mar 2025 16:44:34 -0400 Subject: [PATCH 44/51] chore(deps): bump vyper from 0.3.10 to 0.4.0 (#1806) Bumps [vyper](https://github.com/vyperlang/vyper) from 0.3.10 to 0.4.0. - [Release notes](https://github.com/vyperlang/vyper/releases) - [Changelog](https://github.com/vyperlang/vyper/blob/master/docs/release-notes.rst) - [Commits](https://github.com/vyperlang/vyper/compare/v0.3.10...v0.4.0) --- updated-dependencies: - dependency-name: vyper dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements-windows.txt | 7 +++---- requirements.txt | 5 ----- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/requirements-windows.txt b/requirements-windows.txt index 4e27a2174..3639a50f2 100644 --- a/requirements-windows.txt +++ b/requirements-windows.txt @@ -77,7 +77,6 @@ eth-hash[pycryptodome]==0.6.0 # -r requirements.txt # eip712 # eth-event - # eth-hash # eth-utils # web3 eth-keyfile==0.7.0 @@ -173,6 +172,7 @@ packaging==23.2 # -r requirements.txt # black # pytest + # vvm # vyper parsimonious==0.9.0 # via @@ -267,7 +267,6 @@ semantic-version==2.10.0 # via # -r requirements.txt # py-solc-x - # vvm six==1.16.0 # via # -r requirements.txt @@ -297,9 +296,9 @@ urllib3==2.2.1 # via # -r requirements.txt # requests -vvm==0.1.0 +vvm==0.2.1 # via -r requirements.txt -vyper==0.3.10 +vyper==0.4.0 # via -r requirements.txt wcwidth==0.2.13 # via diff --git a/requirements.txt b/requirements.txt index 26e114aa2..34d8692ea 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,8 +10,6 @@ aiosignal==1.3.1 # via aiohttp asttokens==2.4.1 # via vyper -async-timeout==4.0.3 - # via aiohttp attrs==23.2.0 # via # aiohttp @@ -215,15 +213,12 @@ sortedcontainers==2.4.0 # via hypothesis toml==0.10.2 # via pytest -tomli==2.0.1 - # via black toolz==0.12.1 # via cytoolz tqdm==4.66.2 # via -r requirements.in typing-extensions==4.9.0 # via - # black # eth-rlp # eth-typing # web3 From 6e85693068af64265ff8d6890a0ebf8c215662d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Mar 2025 16:46:34 -0400 Subject: [PATCH 45/51] chore(deps): bump virtualenv from 20.25.1 to 20.26.6 (#1805) Bumps [virtualenv](https://github.com/pypa/virtualenv) from 20.25.1 to 20.26.6. - [Release notes](https://github.com/pypa/virtualenv/releases) - [Changelog](https://github.com/pypa/virtualenv/blob/main/docs/changelog.rst) - [Commits](https://github.com/pypa/virtualenv/compare/20.25.1...20.26.6) --- updated-dependencies: - dependency-name: virtualenv dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 3f5ed5f74..a2444f02b 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -221,7 +221,7 @@ urllib3==2.2.1 # -c requirements.txt # requests # twine -virtualenv==20.25.1 +virtualenv==20.26.6 # via tox wheel==0.42.0 # via From a6ccea7f869a3ad69c16c463cf52cffba6a4a123 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Mar 2025 16:47:35 -0400 Subject: [PATCH 46/51] chore(deps): bump eth-abi from 5.0.0 to 5.0.1 (#1755) Bumps [eth-abi](https://github.com/ethereum/eth-abi) from 5.0.0 to 5.0.1. - [Release notes](https://github.com/ethereum/eth-abi/releases) - [Changelog](https://github.com/ethereum/eth-abi/blob/main/docs/release_notes.rst) - [Commits](https://github.com/ethereum/eth-abi/compare/v5.0.0...v5.0.1) --- updated-dependencies: - dependency-name: eth-abi dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements-windows.txt | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements-windows.txt b/requirements-windows.txt index 3639a50f2..935522863 100644 --- a/requirements-windows.txt +++ b/requirements-windows.txt @@ -58,7 +58,7 @@ dataclassy==0.11.1 # eip712 eip712==0.2.4 # via -r requirements.txt -eth-abi==5.0.0 +eth-abi==5.0.1 # via # -r requirements.txt # eip712 diff --git a/requirements.txt b/requirements.txt index 34d8692ea..bebc7bbfd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -37,7 +37,7 @@ dataclassy==0.11.1 # via eip712 eip712==0.2.4 # via -r requirements.in -eth-abi==5.0.0 +eth-abi==5.0.1 # via # -r requirements.in # eip712 From 5850bcd7a642007c792d2a75932333a8ccb793a3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Mar 2025 16:48:22 -0400 Subject: [PATCH 47/51] chore(deps): bump tqdm from 4.66.2 to 4.66.3 (#1766) Bumps [tqdm](https://github.com/tqdm/tqdm) from 4.66.2 to 4.66.3. - [Release notes](https://github.com/tqdm/tqdm/releases) - [Commits](https://github.com/tqdm/tqdm/compare/v4.66.2...v4.66.3) --- updated-dependencies: - dependency-name: tqdm dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements-windows.txt | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements-windows.txt b/requirements-windows.txt index 935522863..f869d24bc 100644 --- a/requirements-windows.txt +++ b/requirements-windows.txt @@ -284,7 +284,7 @@ toolz==0.12.1 # via # -r requirements.txt # cytoolz -tqdm==4.66.2 +tqdm==4.66.3 # via -r requirements.txt typing-extensions==4.9.0 # via diff --git a/requirements.txt b/requirements.txt index bebc7bbfd..bb8e464c1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -215,7 +215,7 @@ toml==0.10.2 # via pytest toolz==0.12.1 # via cytoolz -tqdm==4.66.2 +tqdm==4.66.3 # via -r requirements.in typing-extensions==4.9.0 # via From 1d0a328c337b3c6de0cfe65e7540a3833df63c2e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Mar 2025 16:51:24 -0400 Subject: [PATCH 48/51] chore(deps): bump jinja2 from 3.1.3 to 3.1.6 (#1813) Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.3 to 3.1.6. - [Release notes](https://github.com/pallets/jinja/releases) - [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/jinja/compare/3.1.3...3.1.6) --- updated-dependencies: - dependency-name: jinja2 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index a2444f02b..d07d53b91 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -85,7 +85,7 @@ jeepney==0.8.0 # via # keyring # secretstorage -jinja2==3.1.3 +jinja2==3.1.6 # via sphinx keyring==24.3.0 # via twine From db006ee8673f57e2034d4208fef11c2a5ee3511a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Mar 2025 17:04:00 -0400 Subject: [PATCH 49/51] chore(deps): bump aiohttp from 3.9.3 to 3.10.11 (#1795) Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.9.3 to 3.10.11. - [Release notes](https://github.com/aio-libs/aiohttp/releases) - [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) - [Commits](https://github.com/aio-libs/aiohttp/compare/v3.9.3...v3.10.11) --- updated-dependencies: - dependency-name: aiohttp dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements-windows.txt | 17 +++++++++++++++-- requirements.txt | 10 ++++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/requirements-windows.txt b/requirements-windows.txt index f869d24bc..c0c1c30da 100644 --- a/requirements-windows.txt +++ b/requirements-windows.txt @@ -4,7 +4,11 @@ # # pip-compile requirements-windows.in # -aiohttp==3.9.3 +aiohappyeyeballs==2.6.1 + # via + # -r requirements.txt + # aiohttp +aiohttp==3.11.0b0 # via # -r requirements.txt # web3 @@ -34,6 +38,8 @@ cbor2==5.6.2 # via # -r requirements.txt # vyper +cchecksum==0.0.7 + # via -r requirements.txt certifi==2024.2.2 # via # -r requirements.txt @@ -95,6 +101,7 @@ eth-rlp==1.0.1 eth-typing==3.5.2 # via # -r requirements.txt + # cchecksum # eip712 # eth-abi # eth-keys @@ -103,6 +110,7 @@ eth-typing==3.5.2 eth-utils==2.3.1 # via # -r requirements.txt + # cchecksum # eip712 # eth-abi # eth-account @@ -192,6 +200,11 @@ pluggy==1.4.0 # pytest prompt-toolkit==3.0.43 # via -r requirements.txt +propcache==0.3.0 + # via + # -r requirements.txt + # aiohttp + # yarl protobuf==4.25.3 # via # -r requirements.txt @@ -316,7 +329,7 @@ wheel==0.42.0 # vyper wrapt==1.16.0 # via -r requirements.txt -yarl==1.9.4 +yarl==1.18.3 # via # -r requirements.txt # aiohttp diff --git a/requirements.txt b/requirements.txt index bb8e464c1..f9dc52ac6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,9 @@ # # pip-compile requirements.in # -aiohttp==3.9.3 +aiohappyeyeballs==2.6.1 + # via aiohttp +aiohttp==3.11.0b0 # via web3 aiosignal==1.3.1 # via aiohttp @@ -141,6 +143,10 @@ pluggy==1.4.0 # via pytest prompt-toolkit==3.0.43 # via -r requirements.in +propcache==0.3.0 + # via + # aiohttp + # yarl protobuf==4.25.3 # via web3 psutil==5.9.8 @@ -238,7 +244,7 @@ wheel==0.42.0 # via vyper wrapt==1.16.0 # via -r requirements.in -yarl==1.9.4 +yarl==1.18.3 # via aiohttp zipp==3.17.0 # via importlib-metadata From b4af9c51fd1aee631c47dbce720e7223296ea98f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Mar 2025 17:04:20 -0400 Subject: [PATCH 50/51] chore(deps): bump cryptography from 42.0.5 to 44.0.1 (#1808) Bumps [cryptography](https://github.com/pyca/cryptography) from 42.0.5 to 44.0.1. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/42.0.5...44.0.1) --- updated-dependencies: - dependency-name: cryptography dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index d07d53b91..b472d66f2 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -47,7 +47,7 @@ coverage[toml]==7.4.3 # via # -r requirements-dev.in # pytest-cov -cryptography==42.0.5 +cryptography==44.0.1 # via secretstorage distlib==0.3.8 # via virtualenv From 230ef55131ac32af7990e9c056b27a37766e9461 Mon Sep 17 00:00:00 2001 From: kx9x Date: Thu, 20 Mar 2025 18:30:43 -0700 Subject: [PATCH 51/51] [fix] GethPOAMiddleware on Polygon networks with anvil fork (#1791) * [fix] GethPOAMiddleware on development anvil network * chore: constant folding * Update geth_poa.py * Update geth_poa.py --------- Co-authored-by: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> --- brownie/network/middlewares/geth_poa.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/brownie/network/middlewares/geth_poa.py b/brownie/network/middlewares/geth_poa.py index b86265d6a..6f232c42c 100644 --- a/brownie/network/middlewares/geth_poa.py +++ b/brownie/network/middlewares/geth_poa.py @@ -10,9 +10,12 @@ class GethPOAMiddleware(BrownieMiddlewareABC): @classmethod def get_layer(cls, w3: Web3, network_type: str) -> Optional[int]: - block_ident = "latest" if network_type == "live" else 0 + # NOTE: 0 because Ganache sometimes injects a block of their own. It doesn't have the extra data that we are checking for. + # "latest" because On Polygon networks, anvil in forked development mode doesn't throw ExtraDataLengthError on the first block. + block_idents = ("latest",) if network_type == "live" else (0, "latest") try: - w3.eth.get_block(block_ident) + for block_ident in block_idents: + w3.eth.get_block(block_ident) return None except ExtraDataLengthError: return -1