Skip to content

Commit 4685ab1

Browse files
committed
Add new mysterious Petersburg fork
1 parent 6abf213 commit 4685ab1

File tree

8 files changed

+229
-0
lines changed

8 files changed

+229
-0
lines changed

eth/vm/forks/petersburg/__init__.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from typing import ( # noqa: F401
2+
Type,
3+
)
4+
5+
from eth.rlp.blocks import BaseBlock # noqa: F401
6+
from eth.vm.forks.byzantium import (
7+
ByzantiumVM,
8+
get_uncle_reward,
9+
)
10+
from eth.vm.state import BaseState # noqa: F401
11+
12+
from .blocks import PetersburgBlock
13+
from .constants import EIP1234_BLOCK_REWARD
14+
from .headers import (
15+
compute_petersburg_difficulty,
16+
configure_petersburg_header,
17+
create_petersburg_header_from_parent,
18+
)
19+
from .state import PetersburgState
20+
21+
22+
class PetersburgVM(ByzantiumVM):
23+
# fork name
24+
fork = 'petersburg'
25+
26+
# classes
27+
block_class = PetersburgBlock # type: Type[BaseBlock]
28+
_state_class = PetersburgState # type: Type[BaseState]
29+
30+
# Methods
31+
create_header_from_parent = staticmethod(create_petersburg_header_from_parent) # type: ignore # noqa: E501
32+
compute_difficulty = staticmethod(compute_petersburg_difficulty) # type: ignore
33+
configure_header = configure_petersburg_header
34+
get_uncle_reward = staticmethod(get_uncle_reward(EIP1234_BLOCK_REWARD))
35+
36+
@staticmethod
37+
def get_block_reward() -> int:
38+
return EIP1234_BLOCK_REWARD

eth/vm/forks/petersburg/blocks.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from rlp.sedes import (
2+
CountableList,
3+
)
4+
from eth.rlp.headers import (
5+
BlockHeader,
6+
)
7+
from eth.vm.forks.byzantium.blocks import (
8+
ByzantiumBlock,
9+
)
10+
11+
from .transactions import (
12+
PetersburgTransaction,
13+
)
14+
15+
16+
class PetersburgBlock(ByzantiumBlock):
17+
transaction_class = PetersburgTransaction
18+
fields = [
19+
('header', BlockHeader),
20+
('transactions', CountableList(transaction_class)),
21+
('uncles', CountableList(BlockHeader))
22+
]
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from eth_utils.toolz import (
2+
merge,
3+
)
4+
5+
from eth.vm.forks.byzantium.computation import (
6+
BYZANTIUM_PRECOMPILES
7+
)
8+
from eth.vm.forks.byzantium.computation import (
9+
ByzantiumComputation
10+
)
11+
from eth.vm.gas_meter import (
12+
allow_negative_refund_strategy,
13+
GasMeter,
14+
)
15+
16+
from .opcodes import PETERSBURG_OPCODES
17+
18+
PETERSBURG_PRECOMPILES = merge(
19+
BYZANTIUM_PRECOMPILES,
20+
{
21+
# TODO: add new precompiles
22+
},
23+
)
24+
25+
26+
class PetersburgComputation(ByzantiumComputation):
27+
"""
28+
A class for all execution computations in the ``Petersburg`` fork.
29+
Inherits from :class:`~eth.vm.forks.byzantium.computation.ByzantiumComputation`
30+
"""
31+
# Override
32+
opcodes = PETERSBURG_OPCODES
33+
_precompiles = PETERSBURG_PRECOMPILES
34+
35+
def get_gas_meter(self) -> GasMeter:
36+
return GasMeter(
37+
self.msg.gas,
38+
allow_negative_refund_strategy
39+
)

eth/vm/forks/petersburg/constants.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from eth_utils import denoms
2+
3+
4+
GAS_EXTCODEHASH_EIP1052 = 400
5+
6+
EIP1234_BLOCK_REWARD = 2 * denoms.ether

eth/vm/forks/petersburg/headers.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from eth.vm.forks.byzantium.headers import (
2+
configure_header,
3+
create_header_from_parent,
4+
compute_difficulty,
5+
)
6+
7+
8+
compute_petersburg_difficulty = compute_difficulty(5000000)
9+
10+
create_petersburg_header_from_parent = create_header_from_parent(
11+
compute_petersburg_difficulty
12+
)
13+
configure_petersburg_header = configure_header(compute_petersburg_difficulty)

eth/vm/forks/petersburg/opcodes.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import copy
2+
from eth_utils.toolz import (
3+
merge
4+
)
5+
6+
from eth import (
7+
constants
8+
)
9+
from eth.vm import (
10+
mnemonics,
11+
opcode_values,
12+
)
13+
from eth.vm.forks.byzantium.opcodes import (
14+
BYZANTIUM_OPCODES,
15+
)
16+
from eth.vm.forks.petersburg.constants import (
17+
GAS_EXTCODEHASH_EIP1052
18+
)
19+
from eth.vm.logic import (
20+
arithmetic,
21+
context,
22+
system,
23+
)
24+
from eth.vm.opcode import (
25+
as_opcode
26+
)
27+
28+
29+
UPDATED_OPCODES = {
30+
opcode_values.SHL: as_opcode(
31+
logic_fn=arithmetic.shl,
32+
mnemonic=mnemonics.SHL,
33+
gas_cost=constants.GAS_VERYLOW,
34+
),
35+
opcode_values.SHR: as_opcode(
36+
logic_fn=arithmetic.shr,
37+
mnemonic=mnemonics.SHR,
38+
gas_cost=constants.GAS_VERYLOW,
39+
),
40+
opcode_values.SAR: as_opcode(
41+
logic_fn=arithmetic.sar,
42+
mnemonic=mnemonics.SAR,
43+
gas_cost=constants.GAS_VERYLOW,
44+
),
45+
opcode_values.EXTCODEHASH: as_opcode(
46+
logic_fn=context.extcodehash,
47+
mnemonic=mnemonics.EXTCODEHASH,
48+
gas_cost=GAS_EXTCODEHASH_EIP1052,
49+
),
50+
opcode_values.CREATE2: system.Create2.configure(
51+
__name__='opcode:CREATE2',
52+
mnemonic=mnemonics.CREATE2,
53+
gas_cost=constants.GAS_CREATE,
54+
)(),
55+
}
56+
57+
PETERSBURG_OPCODES = merge(
58+
copy.deepcopy(BYZANTIUM_OPCODES),
59+
UPDATED_OPCODES,
60+
)

eth/vm/forks/petersburg/state.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from eth.vm.forks.byzantium.state import (
2+
ByzantiumState
3+
)
4+
5+
from .computation import PetersburgComputation
6+
7+
8+
class PetersburgState(ByzantiumState):
9+
computation_class = PetersburgComputation
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from eth_keys.datatypes import PrivateKey
2+
from eth_typing import Address
3+
4+
from eth.vm.forks.byzantium.transactions import (
5+
ByzantiumTransaction,
6+
ByzantiumUnsignedTransaction,
7+
)
8+
9+
from eth._utils.transactions import (
10+
create_transaction_signature,
11+
)
12+
13+
14+
class PetersburgTransaction(ByzantiumTransaction):
15+
@classmethod
16+
def create_unsigned_transaction(cls,
17+
*,
18+
nonce: int,
19+
gas_price: int,
20+
gas: int,
21+
to: Address,
22+
value: int,
23+
data: bytes) -> 'PetersburgUnsignedTransaction':
24+
return PetersburgUnsignedTransaction(nonce, gas_price, gas, to, value, data)
25+
26+
27+
class PetersburgUnsignedTransaction(ByzantiumUnsignedTransaction):
28+
def as_signed_transaction(self,
29+
private_key: PrivateKey,
30+
chain_id: int=None) -> PetersburgTransaction:
31+
v, r, s = create_transaction_signature(self, private_key, chain_id=chain_id)
32+
return PetersburgTransaction(
33+
nonce=self.nonce,
34+
gas_price=self.gas_price,
35+
gas=self.gas,
36+
to=self.to,
37+
value=self.value,
38+
data=self.data,
39+
v=v,
40+
r=r,
41+
s=s,
42+
)

0 commit comments

Comments
 (0)