Skip to content

Commit

Permalink
[WIP] initial dirty commit, getting tests to pass locally with py-evm…
Browse files Browse the repository at this point in the history
… london changes. Change txn_type across codebase to clarify against an actual transaction type that now exists (typed transactions). Some spelling fixes. Some refactoring.
  • Loading branch information
fselmo committed Sep 20, 2021
1 parent c99194c commit 804bdee
Show file tree
Hide file tree
Showing 16 changed files with 197 additions and 100 deletions.
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,8 @@ cannot be found.
'total_difficulty': 262144,
'transactions': (),
'transactions_root': '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421',
'uncles': ()}
'uncles': (),
'base_fee_per_gas': 1000000000}
```


Expand Down Expand Up @@ -447,7 +448,8 @@ cannot be found.
'total_difficulty': 262144,
'transactions': (),
'transactions_root': '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421',
'uncles': ()}
'uncles': (),
'base_fee_per_gas': 1000000000}
```

<a id="api-get_transaction_receipt"></a>
Expand Down Expand Up @@ -806,7 +808,8 @@ to `PyEVM.generate_genesis_params`.
# "receipt_root": BLANK_ROOT_HASH,
# "timestamp": int(time.time()),
# "transaction_root": BLANK_ROOT_HASH,
# "uncles_hash": EMPTY_RLP_LIST_HASH
# "uncles_hash": EMPTY_RLP_LIST_HASH,
# "base_fee_per_gas": 1000000000,
# }
```

Expand Down
1 change: 1 addition & 0 deletions eth_tester/backends/mock/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ def make_genesis_block(overrides=None):
"timestamp": int(time.time()),
"transactions": [],
"uncles": [],
"base_fee_per_gas": 1000000000,
}
if overrides is not None:
genesis_block = merge_genesis_overrides(defaults=default_genesis_block,
Expand Down
16 changes: 8 additions & 8 deletions eth_tester/backends/pyevm/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,20 +120,20 @@ def generate_genesis_state_for_keys(account_keys, overrides=None):

def get_default_genesis_params(overrides=None):
default_genesis_params = {
"bloom": 0,
# "bloom": 0,
"coinbase": GENESIS_COINBASE,
"difficulty": GENESIS_DIFFICULTY,
"extra_data": GENESIS_EXTRA_DATA,
"gas_limit": GENESIS_GAS_LIMIT,
"gas_used": 0,
# "gas_used": 0,
"mix_hash": GENESIS_MIX_HASH,
"nonce": GENESIS_NONCE,
"block_number": GENESIS_BLOCK_NUMBER,
"parent_hash": GENESIS_PARENT_HASH,
# "block_number": GENESIS_BLOCK_NUMBER,
# "parent_hash": GENESIS_PARENT_HASH,
"receipt_root": BLANK_ROOT_HASH,
"timestamp": int(time.time()),
"transaction_root": BLANK_ROOT_HASH,
"uncles_hash": EMPTY_RLP_LIST_HASH
# "uncles_hash": EMPTY_RLP_LIST_HASH,
}
if overrides is not None:
genesis_params = merge_genesis_overrides(default_genesis_params, overrides=overrides)
Expand All @@ -156,8 +156,8 @@ def setup_tester_chain(
from eth.db import get_db_backend

if vm_configuration is None:
from eth.vm.forks import BerlinVM
no_proof_vms = ((0, BerlinVM.configure(consensus_class=NoProofConsensus)),)
from eth.vm.forks import LondonVM
no_proof_vms = ((0, LondonVM.configure(consensus_class=NoProofConsensus)),)
else:
consensus_applier = ConsensusApplier(NoProofConsensus)
no_proof_vms = consensus_applier.amend_vm_configuration(vm_configuration)
Expand Down Expand Up @@ -435,7 +435,7 @@ def _normalize_transaction(self, transaction, block_number='latest'):
if 'data' not in transaction:
yield 'data', b''
if 'gas_price' not in transaction:
yield 'gas_price', 1
yield 'gas_price', 1000000000
if 'value' not in transaction:
yield 'value', 0
if 'to' not in transaction:
Expand Down
10 changes: 10 additions & 0 deletions eth_tester/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,23 @@
FORK_SPURIOUS_DRAGON = 'FORK_SPURIOUS_DRAGON'
FORK_TANGERINE_WHISTLE = 'FORK_TANGERINE_WHISTLE'
FORK_BYZANTIUM = 'FORK_BYZANTIUM'
FORK_PETERSBURG = 'FORK_PETERSBURG'
FORK_ISTANBUL = 'FORK_ISTANBUL'
FORK_MUIR_GLACIER = 'FORK_MUIR_GLACIER'
FORK_BERLIN = 'FORK_BERLIN'
FORK_LONDON = 'FORK_LONDON'

KNOWN_FORKS = {
FORK_HOMESTEAD,
FORK_DAO,
FORK_SPURIOUS_DRAGON,
FORK_TANGERINE_WHISTLE,
FORK_BYZANTIUM,
FORK_PETERSBURG,
FORK_ISTANBUL,
FORK_MUIR_GLACIER,
FORK_BERLIN,
FORK_LONDON,
}


Expand Down
13 changes: 8 additions & 5 deletions eth_tester/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ def _pop_pending_transactions_to_pending_block(self):
def _add_all_to_pending_block(self, pending_transactions):
for pending in pending_transactions:
txn = extract_valid_transaction_params(pending)
yield self._add_transaction_to_pending_block(txn, txn_type='send_signed')
yield self._add_transaction_to_pending_block(txn, txn_internal_type='send_signed')

#
# Transaction Sending
Expand Down Expand Up @@ -419,7 +419,7 @@ def send_transaction(self, transaction):
return self._add_transaction_to_pending_block(transaction)

def call(self, transaction, block_number="latest"):
self.validator.validate_inbound_transaction(transaction, txn_type='call')
self.validator.validate_inbound_transaction(transaction, txn_internal_type='call')
raw_transaction = self.normalizer.normalize_inbound_transaction(transaction)
self.validator.validate_inbound_block_number(block_number)
raw_block_number = self.normalizer.normalize_inbound_block_number(block_number)
Expand All @@ -429,7 +429,7 @@ def call(self, transaction, block_number="latest"):
return result

def estimate_gas(self, transaction, block_number="latest"):
self.validator.validate_inbound_transaction(transaction, txn_type='estimate')
self.validator.validate_inbound_transaction(transaction, txn_internal_type='estimate')
raw_transaction = self.normalizer.normalize_inbound_transaction(transaction)
self.validator.validate_inbound_block_number(block_number)
raw_block_number = self.normalizer.normalize_inbound_block_number(block_number)
Expand All @@ -441,8 +441,11 @@ def estimate_gas(self, transaction, block_number="latest"):
#
# Private Transaction API
#
def _add_transaction_to_pending_block(self, transaction, txn_type='send'):
self.validator.validate_inbound_transaction(transaction, txn_type=txn_type)
def _add_transaction_to_pending_block(self, transaction, txn_internal_type='send'):
self.validator.validate_inbound_transaction(
transaction,
txn_internal_type=txn_internal_type
)
raw_transaction = self.normalizer.normalize_inbound_transaction(transaction)

if raw_transaction['from'] in self._account_passwords:
Expand Down
5 changes: 5 additions & 0 deletions eth_tester/normalization/inbound.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,18 @@ def normalize_private_key(value):
))

TRANSACTION_NORMALIZERS = {
'chain_id': identity,
'type': identity,
'from': to_canonical_address,
'to': to_empty_or_canonical_address,
'gas': identity,
'gas_price': identity,
'max_fee_per_gas': identity,
'max_priority_fee_per_gas': identity,
'nonce': identity,
'value': identity,
'data': decode_hex,
'access_list': identity,
'r': identity,
's': identity,
'v': identity,
Expand Down
8 changes: 6 additions & 2 deletions eth_tester/normalization/outbound.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
))

TRANSACTION_NORMALIZERS = {
"chain_id": identity,
"type": identity,
"hash": encode_hex,
"nonce": identity,
"block_hash": partial(normalize_if, conditional_fn=is_bytes, normalizer=encode_hex),
Expand All @@ -42,13 +44,14 @@
"value": identity,
"gas": identity,
"gas_price": identity,
"max_fee_per_gas": identity,
"max_priority_fee_per_gas": identity,
"data": encode_hex,
"access_list": identity,
"v": identity,
"r": identity,
"s": identity,
}


normalize_transaction = partial(normalize_dict, normalizers=TRANSACTION_NORMALIZERS)


Expand All @@ -65,6 +68,7 @@ def is_transaction_object_list(value):
"hash": encode_hex,
"parent_hash": encode_hex,
"nonce": encode_hex,
"base_fee_per_gas": identity,
"sha3_uncles": encode_hex,
"logs_bloom": identity,
"transactions_root": encode_hex,
Expand Down
12 changes: 8 additions & 4 deletions eth_tester/utils/backend_testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
PK_A = '0x58d23b55bc9cdce1f18c2500f40ff4ab7245df9a89505e9b1fa4851f623d241d'
PK_A_ADDRESS = '0xdc544d1aa88ff8bbd2f2aec754b1f1e99e1812fd'

NON_DEFAULT_GAS_PRICE = 504
NON_DEFAULT_GAS_PRICE = 1000000000

SIMPLE_TRANSACTION = {
"to": BURN_ADDRESS,
Expand Down Expand Up @@ -96,11 +96,13 @@
"timestamp",
"transactions",
"uncles",
"base_fee_per_gas",
}


def _validate_serialized_block(block):
missing_keys = BLOCK_KEYS.difference(block.keys())
missing_keys = dissoc(missing_keys, 'base_fee_per_gas')
if missing_keys:
error_message = "Serialized block is missing the following keys: {}".format(
"|".join(sorted(missing_keys)),
Expand Down Expand Up @@ -265,10 +267,12 @@ def test_send_raw_transaction_valid_raw_transaction(self, eth_tester, is_pending
"gas": 21000,
"value": 1 * denoms.ether,
})
# transaction: nonce=0, gas_price=1, gas=21000, to=BURN_ADDRESS, value=50000, data=b'',
# and signed with `test_key`
transaction_hex = "0xf861800182520894dead00000000000000000000000000000000000082c350801ba073128146b850e2d38a4742d1afa48544e0ac6bc4b4dcb562583cd2224ad9a082a0680086a2801d02b12431cc3c79ec6c6a0cb846a0b3a8ec970f6e1b76d55ee7e2" # noqa: E501

# transaction: 'to': '0x19E7E376E7C213B7E7e7e46cc70A5dD086DAff2A', 'from':
# '0x19E7E376E7C213B7E7e7e46cc70A5dD086DAff2A', 'value': 1337, 'nonce': 0
# 'gas': 21000, 'gasPrice': 1000000000, and signed with `test_key`

transaction_hex = "0xf86580843b9aca008252089419e7e376e7c213b7e7e7e46cc70a5dd086daff2a820539801ba0b101c1f9dc0c588c0194a1093f06e6b30d1fd16d31014ef5851311b7bfbf419ea01cfa8757b7863a630ef7491c62b03d9cd9dff395f61b5df500cc665f0fa5b027" # noqa: E501
if is_pending:
eth_tester.disable_auto_mine_transactions()

Expand Down
5 changes: 5 additions & 0 deletions eth_tester/utils/transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@


VALID_TRANSACTION_PARAMS = [
'type',
'chain_id',
'from',
'to',
'gas',
'gas_price',
'max_fee_per_gas',
'max_priority_fee_per_gas',
'value',
'data',
'nonce',
'access_list',
'r',
's',
'v',
Expand Down
2 changes: 1 addition & 1 deletion eth_tester/validation/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def validate_inbound_raw_transaction(self, raw_transaction_hex):
def validate_inbound_timestamp(self, timestamp):
raise NotImplementedError("must be implemented by subclasses")

def validate_inbound_transaction(self, transaction, txn_type):
def validate_inbound_transaction(self, transaction, txn_internal_type):
raise NotImplementedError("must be implemented by subclasses")

def validate_inbound_transaction_hash(self, transaction_hash):
Expand Down
25 changes: 23 additions & 2 deletions eth_tester/validation/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

import functools

from toolz import dissoc

from eth_utils import (
is_boolean,
is_bytes,
Expand Down Expand Up @@ -111,6 +113,7 @@ def validate_no_extra_keys(value, allowed_keys):

def validate_has_required_keys(value, required_keys):
missing_keys = tuple(sorted(set(required_keys).difference(value.keys())))
missing_keys = dissoc(missing_keys, 'base_fee_per_gas') # pre-london blocks won't have this
if missing_keys:
raise ValidationError(
"Blocks must contain all of the keys '{}'. Missing the keys: '{}'".format(
Expand All @@ -120,10 +123,24 @@ def validate_has_required_keys(value, required_keys):
)


def validate_transaction_params(value):
if "gas_price" in value and any(_ in value for _ in (
"max_fee_per_gas", "max_priority_fee_per_gas"
)):
raise ValidationError("legacy gas price and dynamic fee transaction parameters present")
if "type" in value:
if value["type"] in ("0x1", 1) and "access_list" not in value:
raise ValidationError("type 1 transaction is missing access_list")
if value["type"] in ("0x2", 2) and not all(_ in value for _ in (
"max_fee_per_gas", "max_priority_fee_per_gas"
)):
raise ValidationError("type 2 transaction is missing fee values")


@to_dict
def _accumulate_dict_errors(value, validators):
for key, validator_fn in validators.items():
item = value[key]
item = value.get(key)
try:
validator_fn(item)
except ValidationError as err:
Expand All @@ -133,7 +150,11 @@ def _accumulate_dict_errors(value, validators):
def validate_dict(value, key_validators):
validate_is_dict(value)
validate_no_extra_keys(value, key_validators.keys())
validate_has_required_keys(value, key_validators.keys())
if "to" in key_validators:
# if transaction
validate_transaction_params(value)
else:
validate_has_required_keys(value, key_validators.keys())

key_errors = _accumulate_dict_errors(value, key_validators)
if key_errors:
Expand Down
Loading

0 comments on commit 804bdee

Please sign in to comment.