Skip to content
Open
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
1,747 changes: 818 additions & 929 deletions build/__native_5f8b22f5f815a3776376.c

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions build/__native_internal_5f8b22f5f815a3776376.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

int CPyGlobalsInit(void);

extern PyObject *CPyStatics[2321];
extern PyObject *CPyStatics[2319];
extern const char * const CPyLit_Str[];
extern const char * const CPyLit_Bytes[];
extern const char * const CPyLit_Int[];
Expand Down Expand Up @@ -58,7 +58,6 @@ extern CPyModule *CPyModule_faster_web3___middleware;
extern CPyModule *CPyModule_faster_web3____utils___async_transactions__internal;
extern CPyModule *CPyModule_faster_web3____utils___async_transactions;
extern PyObject *CPyStatic_async_transactions___globals;
extern CPyModule *CPyModule_faster_eth_utils___toolz;
extern CPyModule *CPyModule_faster_web3____utils___transactions;
extern CPyModule *CPyModule_faster_web3____utils___utility_methods__internal;
extern CPyModule *CPyModule_faster_web3____utils___utility_methods;
Expand Down Expand Up @@ -109,6 +108,7 @@ extern CPyModule *CPyModule_faster_web3___utils___abi;
extern CPyModule *CPyModule_faster_web3____utils___datatypes__internal;
extern CPyModule *CPyModule_faster_web3____utils___datatypes;
extern PyObject *CPyStatic_datatypes___globals;
extern CPyModule *CPyModule_faster_eth_utils___toolz;
extern CPyModule *CPyModule_faster_web3____utils___decorators__internal;
extern CPyModule *CPyModule_faster_web3____utils___decorators;
extern PyObject *CPyStatic_decorators___globals;
Expand Down
6 changes: 2 additions & 4 deletions faster_web3/_utils/async_transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@
from eth_typing import (
ChecksumAddress,
)
from faster_eth_utils.toolz import (
assoc,
)
from faster_hexbytes import (
HexBytes,
)
Expand Down Expand Up @@ -119,7 +116,8 @@ async def async_fill_nonce(
cast(ChecksumAddress, transaction["from"]),
block_identifier="pending",
)
return assoc(transaction, "nonce", tx_count)
transaction = transaction.copy()
transaction["nonce"] = tx_count
return transaction


Expand Down
9 changes: 4 additions & 5 deletions faster_web3/_utils/module_testing/eth_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@
remove_0x_prefix,
to_bytes,
)
from faster_eth_utils.toolz import (
assoc,
)
from faster_hexbytes import (
HexBytes,
)
Expand Down Expand Up @@ -867,7 +864,8 @@ async def test_gas_price_from_strategy_bypassed_for_dynamic_fee_txn(
"maxPriorityFeePerGas": max_priority_fee,
}
if max_fee is not None:
txn_params = assoc(txn_params, "maxFeePerGas", max_fee)
txn_params = txn_params.copy()
txn_params["maxFeePerGas"] = max_fee

def gas_price_strategy(w3: "Web3", txn: TxParams) -> Wei:
return async_w3.to_wei(2, "gwei")
Expand Down Expand Up @@ -3466,7 +3464,8 @@ def test_gas_price_from_strategy_bypassed_for_dynamic_fee_txn(
"maxPriorityFeePerGas": max_priority_fee,
}
if max_fee is not None:
txn_params = assoc(txn_params, "maxFeePerGas", max_fee)
txn_params = txn_params.copy()
txn_params["maxFeePerGas"] = max_fee

def gas_price_strategy(_w3: "Web3", _txn: TxParams) -> Wei:
return w3.to_wei(2, "gwei")
Expand Down
38 changes: 15 additions & 23 deletions faster_web3/_utils/transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
ChecksumAddress,
)
from faster_eth_utils.toolz import (
assoc,
curry,
)
from faster_hexbytes import (
Expand Down Expand Up @@ -98,15 +97,11 @@
@curry
def fill_nonce(w3: "Web3", transaction: TxParams) -> TxParams:
if "from" in transaction and "nonce" not in transaction:
return assoc(
transaction,
"nonce",
w3.eth.get_transaction_count(
cast(ChecksumAddress, transaction["from"]), block_identifier="pending"
),
transaction = transaction.copy()
transaction["nonce"] = w3.eth.get_transaction_count(
cast(ChecksumAddress, transaction["from"]), block_identifier="pending"
)
else:
return transaction
return transaction


@curry
Expand Down Expand Up @@ -214,9 +209,9 @@ def extract_valid_transaction_params(transaction_params: TxData) -> TxParams:
return extracted_params
elif extracted_params.get("data") is None:
if transaction_params.get("input") is not None:
return assoc(extracted_params, "data", transaction_params["input"])
else:
return extracted_params
extracted_params = extracted_params.copy()
extracted_params["data"] = transaction_params["input"]
return extracted_params
else:
raise Exception(
"Unreachable path: transaction's 'data' is either set or not set"
Expand Down Expand Up @@ -248,9 +243,8 @@ def prepare_replacement_transaction(
)

if "nonce" not in replacement_transaction:
replacement_transaction = assoc(
replacement_transaction, "nonce", original_transaction["nonce"]
)
replacement_transaction = replacement_transaction.copy()
replacement_transaction["nonce"] = original_transaction["nonce"]

if any_in_dict(DYNAMIC_FEE_TXN_PARAMS, replacement_transaction):
# for now, the client decides if a dynamic fee txn can replace
Expand All @@ -271,14 +265,12 @@ def prepare_replacement_transaction(
minimum_gas_price = int(
math.ceil(original_transaction["gasPrice"] * gas_multiplier)
)
if generated_gas_price and generated_gas_price > minimum_gas_price:
replacement_transaction = assoc(
replacement_transaction, "gasPrice", generated_gas_price
)
else:
replacement_transaction = assoc(
replacement_transaction, "gasPrice", minimum_gas_price
)
replacement_transaction = replacement_transaction.copy()
replacement_transaction["gasPrice"] = (
generated_gas_price
if generated_gas_price and generated_gas_price > minimum_gas_price
else minimum_gas_price
)

return replacement_transaction

Expand Down
25 changes: 15 additions & 10 deletions faster_web3/eth/base_eth.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@
is_checksum_address,
is_string,
)
from faster_eth_utils.toolz import (
assoc,
)

from faster_web3._utils.empty import (
Empty,
Expand Down Expand Up @@ -80,9 +77,11 @@ def default_account(self, account: Union[ChecksumAddress, Empty]) -> None:
self._default_account = account

def send_transaction_munger(self, transaction: TxParams) -> Tuple[TxParams]:
if "from" not in transaction and is_checksum_address(self.default_account):
transaction = assoc(transaction, "from", self.default_account)

if "from" not in transaction:
default_account = self.default_account
if is_checksum_address(default_account):
transaction = transaction.copy()
transaction["from"] = default_account
return (transaction,)

def generate_gas_price(
Expand All @@ -107,8 +106,11 @@ def _eth_call_and_estimate_gas_munger(
Tuple[TxParams, BlockIdentifier, StateOverride],
]:
# TODO: move to middleware
if "from" not in transaction and is_checksum_address(self.default_account):
transaction = assoc(transaction, "from", self.default_account)
if "from" not in transaction:
default_account = self.default_account
if is_checksum_address(default_account):
transaction = transaction.copy()
transaction["from"] = default_account

# TODO: move to middleware
if block_identifier is None:
Expand Down Expand Up @@ -173,8 +175,11 @@ def create_access_list_munger(
self, transaction: TxParams, block_identifier: Optional[BlockIdentifier] = None
) -> Tuple[TxParams, BlockIdentifier]:
# TODO: move to middleware
if "from" not in transaction and is_checksum_address(self.default_account):
transaction = assoc(transaction, "from", self.default_account)
if "from" not in transaction:
default_account = self.default_account
if is_checksum_address(default_account):
transaction = transaction.copy()
transaction["from"] = default_account

# TODO: move to middleware
if block_identifier is None:
Expand Down
14 changes: 5 additions & 9 deletions faster_web3/middleware/buffered_gas_estimate.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
cast,
)

from faster_eth_utils.toolz import (
assoc,
)

from faster_web3._utils.async_transactions import (
get_buffered_gas_estimate as async_get_buffered_gas_estimate,
)
Expand Down Expand Up @@ -37,10 +33,9 @@ def request_processor(self, method: "RPCEndpoint", params: Any) -> Any:
if method == "eth_sendTransaction":
transaction = params[0]
if "gas" not in transaction:
transaction = assoc(
transaction,
"gas",
hex(get_buffered_gas_estimate(cast("Web3", self._w3), transaction)),
transaction = transaction.copy()
transaction["gas"] = hex(
get_buffered_gas_estimate(cast("Web3", self._w3), transaction)
)
params = (transaction,)
return method, params
Expand All @@ -54,6 +49,7 @@ async def async_request_processor(self, method: "RPCEndpoint", params: Any) -> A
gas_estimate = await async_get_buffered_gas_estimate(
cast("AsyncWeb3[Any]", self._w3), transaction
)
transaction = assoc(transaction, "gas", hex(gas_estimate))
transaction = transaction.copy()
transaction["gas"] = hex(gas_estimate)
params = (transaction,)
return method, params
20 changes: 7 additions & 13 deletions faster_web3/middleware/formatting.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
)

from faster_eth_utils.toolz import (
assoc,
curry,
)

Expand Down Expand Up @@ -55,6 +54,8 @@ def _apply_response_formatters(
error_formatters: Formatters,
response: RPCResponse,
) -> RPCResponse:
response = response.copy()

def _format_response(
response_type: Literal["result", "error", "params"],
method_response_formatter: Callable[..., Any],
Expand All @@ -63,19 +64,12 @@ def _format_response(

if response_type == "params":
appropriate_response = cast(EthSubscriptionParams, response[response_type])
return assoc(
response,
response_type,
assoc(
response["params"],
"result",
method_response_formatter(appropriate_response["result"]),
),
)
params = response["params"].copy()
params["result"] = method_response_formatter(appropriate_response["result"])
response[response_type] = params
else:
return assoc(
response, response_type, method_response_formatter(appropriate_response)
)
response[response_type] = method_response_formatter(appropriate_response)
return response

if not isinstance(response, dict):
raise BadResponseFormat(
Expand Down
12 changes: 4 additions & 8 deletions faster_web3/middleware/gas_price_strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
cast,
)

from faster_eth_utils.toolz import (
assoc,
)

from faster_web3._utils.method_formatters import (
to_hex_if_integer,
)
Expand Down Expand Up @@ -49,9 +45,8 @@ def validate_transaction_params(
and "gasPrice" not in transaction
and none_in_dict(DYNAMIC_FEE_TXN_PARAMS, transaction)
):
transaction = assoc(
transaction, "gasPrice", to_hex_if_integer(strategy_based_gas_price)
)
transaction = transaction.copy()
transaction["gasPrice"] = to_hex_if_integer(strategy_based_gas_price)

# legacy and dynamic fee tx variables used:
if "gasPrice" in transaction and any_in_dict(DYNAMIC_FEE_TXN_PARAMS, transaction):
Expand All @@ -67,7 +62,8 @@ def validate_transaction_params(
base_fee = latest_block["baseFeePerGas"]
priority_fee = int(str(transaction["maxPriorityFeePerGas"]), 16)
max_fee_per_gas = priority_fee + 2 * base_fee
transaction = assoc(transaction, "maxFeePerGas", hex(max_fee_per_gas))
transaction = transaction.copy()
transaction["maxFeePerGas"] = hex(max_fee_per_gas)
# dynamic fee transaction - no priority fee:
elif "maxFeePerGas" in transaction and "maxPriorityFeePerGas" not in transaction:
raise InvalidTransaction(
Expand Down
23 changes: 9 additions & 14 deletions faster_web3/providers/eth_tester/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
apply_formatters_to_dict,
)
from faster_eth_utils.toolz import (
assoc,
compose,
curry,
identity,
Expand Down Expand Up @@ -369,12 +368,11 @@ def guess_from(w3: "Web3", _: TxParams) -> ChecksumAddress:
def fill_default(
field: str, guess_func: Callable[..., Any], w3: "Web3", transaction: TxParams
) -> TxParams:
# type ignored b/c TxParams keys must be string literal types
if field in transaction and transaction[field] is not None: # type: ignore [literal-required]
return transaction
else:
if transaction.get(field) is None:
guess_val = guess_func(w3, transaction)
return assoc(transaction, field, guess_val)
transaction = transaction.copy()
transaction[field] = guess_val # type: ignore [literal-required]
return transaction


# --- async --- #
Expand All @@ -384,9 +382,7 @@ async def async_guess_from(
async_w3: "AsyncWeb3[Any]", _: TxParams
) -> Optional[ChecksumAddress]:
accounts = await async_w3.eth.accounts
if accounts is not None and len(accounts) > 0:
return accounts[0]
return None
return accounts[0] if accounts else None


@curry
Expand All @@ -396,12 +392,11 @@ async def async_fill_default(
async_w3: "AsyncWeb3[Any]",
transaction: TxParams,
) -> TxParams:
# type ignored b/c TxParams keys must be string literal types
if field in transaction and transaction[field] is not None: # type: ignore [literal-required]
return transaction
else:
if transaction.get(field) is None:
guess_val = await guess_func(async_w3, transaction)
return assoc(transaction, field, guess_val)
transaction = transaction.copy()
transaction[field] = guess_val # type: ignore [literal-required]
return transaction


# --- define middleware --- #
Expand Down
6 changes: 2 additions & 4 deletions faster_web3/tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@
from faster_eth_utils import (
is_checksum_address,
)
from faster_eth_utils.toolz import (
assoc,
)

from faster_web3._utils.rpc_abi import (
RPC,
Expand Down Expand Up @@ -96,7 +93,8 @@ def trace_call_munger(
if "from" not in transaction and is_checksum_address(
self.w3.eth.default_account
):
transaction = assoc(transaction, "from", self.w3.eth.default_account)
transaction = transaction.copy()
transaction["from"] = self.w3.eth.default_account

if block_identifier is None:
block_identifier = self.default_block
Expand Down