Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Python 3.8 testing (take 2) #1940

Merged
merged 13 commits into from
Jun 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,37 @@ jobs:
environment:
TOXENV: py37-lint

py38-core:
<<: *common
docker:
- image: circleci/python:3.8
environment:
TOXENV: py38-core
py38-database:
<<: *common
docker:
- image: circleci/python:3.8
environment:
TOXENV: py38-database
py38-transactions:
<<: *common
docker:
- image: circleci/python:3.8
environment:
TOXENV: py38-transactions
py38-vm:
<<: *common
docker:
- image: circleci/python:3.8
environment:
TOXENV: py38-vm
py38-lint:
<<: *common
docker:
- image: circleci/python:3.8
environment:
TOXENV: py38-lint

workflows:
version: 2
test:
Expand All @@ -184,12 +215,17 @@ workflows:
- py36-native-blockchain-transition
- py36-vm
- py37-vm
- py38-vm
- py36-core
- py37-core
- py38-core
- py36-transactions
- py37-transactions
- py38-transactions
- py36-database
- py37-database
- py38-database
- py36-docs
- py36-lint
- py37-lint
- py38-lint
8 changes: 4 additions & 4 deletions eth/_utils/transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ def calculate_intrinsic_gas(
else:
create_cost = 0
return (
gas_schedule.gas_tx +
num_zero_bytes * gas_schedule.gas_txdatazero +
num_non_zero_bytes * gas_schedule.gas_txdatanonzero +
create_cost
gas_schedule.gas_tx
+ num_zero_bytes * gas_schedule.gas_txdatazero
+ num_non_zero_bytes * gas_schedule.gas_txdatanonzero
+ create_cost
)
38 changes: 32 additions & 6 deletions eth/abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
TypeVar,
Union,
)
from uuid import UUID

import rlp

Expand Down Expand Up @@ -886,9 +885,9 @@ def __call__(self, computation: 'ComputationAPI') -> None:
def as_opcode(cls: Type[T],
logic_fn: Callable[['ComputationAPI'], None],
mnemonic: str,
gas_cost: int) -> Type[T]:
gas_cost: int) -> T:
"""
Class factory method for turning vanilla functions into Opcode classes.
Class factory method for turning vanilla functions into Opcodes.
"""
...

Expand Down Expand Up @@ -1769,6 +1768,16 @@ def state_root(self) -> Hash32:
"""
...

@state_root.setter
def state_root(self, value: Hash32) -> None:
"""
Force-set the state root hash.
"""
# See: https://github.com/python/mypy/issues/4165
# Since we can't also decorate this with abstract method we want to be
# sure that the setter doesn't actually get used as a noop.
raise NotImplementedError

@abstractmethod
def has_root(self, state_root: bytes) -> bool:
"""
Expand Down Expand Up @@ -1935,6 +1944,22 @@ def commit(self, checkpoint: JournalDBCheckpoint) -> None:
"""
...

@abstractmethod
def lock_changes(self) -> None:
"""
Locks in changes across all accounts' storage databases.

This is typically used at the end of a transaction, to make sure that
a revert doesn't roll back through the previous transaction, and to
be able to look up the "original" value of any account storage, where
"original" is the beginning of a transaction (instead of the beginning
of a block).

See :meth:`eth.abc.AccountStorageDatabaseAPI.lock_changes` for
what is called on each account's storage database.
"""
...

@abstractmethod
def make_state_root(self) -> Hash32:
"""
Expand Down Expand Up @@ -2275,7 +2300,7 @@ def account_is_empty(self, address: Address) -> bool:
# Access self._chaindb
#
@abstractmethod
def snapshot(self) -> Tuple[Hash32, UUID]:
def snapshot(self) -> Tuple[Hash32, JournalDBCheckpoint]:
"""
Perform a full snapshot of the current state.

Expand All @@ -2285,14 +2310,14 @@ def snapshot(self) -> Tuple[Hash32, UUID]:
...

@abstractmethod
def revert(self, snapshot: Tuple[Hash32, UUID]) -> None:
def revert(self, snapshot: Tuple[Hash32, JournalDBCheckpoint]) -> None:
"""
Revert the VM to the state at the snapshot
"""
...

@abstractmethod
def commit(self, snapshot: Tuple[Hash32, UUID]) -> None:
def commit(self, snapshot: Tuple[Hash32, JournalDBCheckpoint]) -> None:
"""
Commit the journal to the point where the snapshot was taken. This
merges in any changes that were recorded since the snapshot.
Expand Down Expand Up @@ -2481,6 +2506,7 @@ class VirtualMachineAPI(ConfigurableAPI):
def __init__(self,
header: BlockHeaderAPI,
chaindb: ChainDatabaseAPI,
chain_context: ChainContextAPI,
consensus_context: ConsensusContextAPI) -> None:
"""
Initialize the virtual machine.
Expand Down
8 changes: 4 additions & 4 deletions eth/chains/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,8 @@ def from_genesis(cls,
# the computed state from the initialized state database.
raise ValidationError(
"The provided genesis state root does not match the computed "
f"genesis state root. Got {state.state_root}. "
f"Expected {genesis_params['state_root']}"
f"genesis state root. Got {state.state_root!r}. "
f"Expected {genesis_params['state_root']!r}"
)

genesis_header = BlockHeader(**genesis_params)
Expand Down Expand Up @@ -463,8 +463,8 @@ def import_block(self,
except HeaderNotFound:
raise ValidationError(
f"Attempt to import block #{block.number}. "
f"Cannot import block {block.hash} before importing "
f"its parent block at {block.header.parent_hash}"
f"Cannot import block {block.hash!r} before importing "
f"its parent block at {block.header.parent_hash!r}"
)

base_header_for_import = self.create_header_from_parent(parent_header)
Expand Down
6 changes: 3 additions & 3 deletions eth/consensus/clique/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,10 @@ def validate_header_integrity(header: BlockHeaderAPI, epoch_length: int) -> None
)

if header.nonce != NONCE_AUTH and header.nonce != NONCE_DROP:
raise ValidationError(f"Invalid nonce: {header.nonce}")
raise ValidationError(f"Invalid nonce: {header.nonce!r}")

if at_checkpoint and header.nonce != NONCE_DROP:
raise ValidationError(f"Invalid checkpoint nonce: {header.nonce}")
raise ValidationError(f"Invalid checkpoint nonce: {header.nonce!r}")

if len(header.extra_data) < VANITY_LENGTH:
raise ValidationError("Missing vanity bytes in extra data")
Expand All @@ -159,7 +159,7 @@ def validate_header_integrity(header: BlockHeaderAPI, epoch_length: int) -> None
raise ValidationError("Checkpoint header must contain list of signers")

if header.mix_hash != ZERO_HASH32:
raise ValidationError(f"Invalid mix hash: {header.mix_hash}")
raise ValidationError(f"Invalid mix hash: {header.mix_hash!r}")

if header.uncles_hash != EMPTY_UNCLE_HASH:
raise ValidationError(f"Invalid uncle hash: {header.uncle_hash}")
Expand Down
2 changes: 1 addition & 1 deletion eth/consensus/clique/datatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def validate_for(self,
if not signer_is_kicked and not signer_is_nominated:
raise ValidationError(
"Must either kick an existing signer or nominate a new signer"
f"Subject: {subject} Current signers: {signers}"
f"Subject: {subject!r} Current signers: {signers}"
)


Expand Down
12 changes: 6 additions & 6 deletions eth/consensus/clique/snapshot_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def create_snapshot_for(self,
try:
new_snapshot = self.get_snapshot(
current_header.block_number, current_header.parent_hash)
except SnapshotNotFound as e:
except SnapshotNotFound:
current_header = self._lookup_header(current_header.parent_hash, cached_parents)

if is_checkpoint(current_header.block_number, self._epoch_length):
Expand Down Expand Up @@ -225,16 +225,16 @@ def get_snapshot(self, block_number: int, block_hash: Hash32) -> Snapshot:
# Otherwise, we can retrieve it on the fly
header = self._chain_db.get_block_header_by_hash(block_hash)
except HeaderNotFound:
raise SnapshotNotFound(f"Can not get snapshot for {block_hash} at {block_number}")
raise SnapshotNotFound(f"Can not get snapshot for {block_hash!r} at {block_number}")
else:
if header.block_number != block_number:
raise SnapshotNotFound(
f"Can not get snapshot for {block_hash} at {block_number}"
f"Can not get snapshot for {block_hash!r} at {block_number}"
)
else:
return self._create_snapshot_from_checkpoint_header(header)

raise SnapshotNotFound(f"Can not get snapshot for {block_hash} at {block_number}")
raise SnapshotNotFound(f"Can not get snapshot for {block_hash!r} at {block_number}")

def add_snapshot(self, mutable_snapshot: MutableSnapshot) -> Snapshot:
"""
Expand All @@ -261,8 +261,8 @@ def get_snapshot_from_db(self, block_hash: Hash32) -> Snapshot:
encoded_key = self._chain_db.db[key]
except KeyError as e:
raise SnapshotNotFound(
f"Can not get on-disk snapshot for {block_hash}"
)
f"Can not get on-disk snapshot for {block_hash!r}"
) from e
else:
return decode_snapshot(encoded_key)

Expand Down
10 changes: 5 additions & 5 deletions eth/db/chain.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def get_block_uncles(self, uncles_hash: Hash32) -> Tuple[BlockHeaderAPI, ...]:
encoded_uncles = self.db[uncles_hash]
except KeyError:
raise HeaderNotFound(
f"No uncles found for hash {uncles_hash}"
f"No uncles found for hash {uncles_hash!r}"
)
else:
return tuple(rlp.decode(encoded_uncles, sedes=rlp.sedes.CountableList(BlockHeader)))
Expand Down Expand Up @@ -141,16 +141,16 @@ def persist_unexecuted_block(self,

if tx_root_hash != block.header.transaction_root:
raise ValidationError(
f"Block's transaction_root ({block.header.transaction_root}) "
f"does not match expected value: {tx_root_hash}"
f"Block's transaction_root ({block.header.transaction_root!r}) "
f"does not match expected value: {tx_root_hash!r}"
)

receipt_root_hash, receipt_kv_nodes = make_trie_root_and_nodes(receipts)

if receipt_root_hash != block.header.receipt_root:
raise ValidationError(
f"Block's receipt_root ({block.header.receipt_root}) "
f"does not match expected value: {receipt_root_hash}"
f"Block's receipt_root ({block.header.receipt_root!r}) "
f"does not match expected value: {receipt_root_hash!r}"
)

with self.db.atomic_batch() as db:
Expand Down
27 changes: 14 additions & 13 deletions eth/db/header.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,22 +79,23 @@ def _update_header_chain_gaps(
cls,
db: DatabaseAPI,
persisted_header: BlockHeaderAPI,
base_gaps: ChainGaps = None) -> GapInfo:
base_gaps: ChainGaps = None
) -> GapInfo:

# If we make many updates in a row, we can avoid reloading the integrity info by
# continuously caching it and providing it as a parameter to this API
if base_gaps is None:
base_gaps = cls._get_header_chain_gaps(db)
# If we make many updates in a row, we can avoid reloading the integrity info by
# continuously caching it and providing it as a parameter to this API
if base_gaps is None:
base_gaps = cls._get_header_chain_gaps(db)

gap_change, gaps = fill_gap(persisted_header.block_number, base_gaps)
gap_change, gaps = fill_gap(persisted_header.block_number, base_gaps)

if gap_change is not GapChange.NoChange:
db.set(
SchemaV1.make_header_chain_gaps_lookup_key(),
rlp.encode(gaps, sedes=chain_gaps)
)
if gap_change is not GapChange.NoChange:
db.set(
SchemaV1.make_header_chain_gaps_lookup_key(),
rlp.encode(gaps, sedes=chain_gaps)
)

return gap_change, gaps
return gap_change, gaps

#
# Canonical Chain API
Expand Down Expand Up @@ -260,7 +261,7 @@ def _persist_checkpoint_header(
# True parent should have already been canonicalized during
# _set_as_canonical_chain_head()
raise ValidationError(
f"Why was a non-matching parent header {parent_hash} left as canonical "
f"Why was a non-matching parent header {parent_hash!r} left as canonical "
f"after _set_as_canonical_chain_head() and {true_parent} is available?"
)

Expand Down
10 changes: 5 additions & 5 deletions eth/precompiles/modexp.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ def _compute_adjusted_exponent_length(exponent_length: int,
else:
first_32_bytes_as_int = big_endian_to_int(first_32_exponent_bytes)
return (
8 * (exponent_length - 32) +
get_highest_bit_index(first_32_bytes_as_int)
8 * (exponent_length - 32)
+ get_highest_bit_index(first_32_bytes_as_int)
)


Expand Down Expand Up @@ -78,9 +78,9 @@ def _compute_modexp_gas_fee(data: bytes) -> int:
complexity = _compute_complexity(max(modulus_length, base_length))

gas_fee = (
complexity *
max(adjusted_exponent_length, 1) //
constants.GAS_MOD_EXP_QUADRATIC_DENOMINATOR
complexity
* max(adjusted_exponent_length, 1)
// constants.GAS_MOD_EXP_QUADRATIC_DENOMINATOR
)
return gas_fee

Expand Down
4 changes: 2 additions & 2 deletions eth/tools/fixtures/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,13 @@ def verify_state(expected_state: AccountState, state: StateAPI) -> None:
if field == 'balance':
error_messages.append(
f"{to_normalized_address(account)}(balance) | "
f"Actual: {actual_value} | Expected: {expected_value} | "
f"Actual: {actual_value!r} | Expected: {expected_value!r} | "
f"Delta: {cast(int, actual_value) - cast(int, expected_value)}"
)
else:
error_messages.append(
f"{to_normalized_address(account)}({field}) | "
f"Actual: {actual_value} | Expected: {expected_value}"
f"Actual: {actual_value!r} | Expected: {expected_value!r}"
)
raise AssertionError(
f"State DB did not match expected state on {len(error_messages)} values:{new_line}"
Expand Down
2 changes: 1 addition & 1 deletion eth/validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def validate_lt(value: int, maximum: int, title: str="Value") -> None:
def validate_canonical_address(value: Address, title: str="Value") -> None:
if not isinstance(value, bytes) or not len(value) == 20:
raise ValidationError(
f"{title} {value} is not a valid canonical address"
f"{title} {value!r} is not a valid canonical address"
)


Expand Down
Loading