Skip to content
This repository has been archived by the owner on Jul 1, 2021. It is now read-only.

Add testnet chain and Xiao Long Bao state machine #489

Merged
42 changes: 24 additions & 18 deletions eth2/beacon/chains/base.py
Original file line number Diff line number Diff line change
@@ -1,50 +1,51 @@
from abc import (
ABC,
abstractmethod
abstractmethod,
)
import logging
from typing import (
TYPE_CHECKING,
Tuple,
Type,
)

import logging

from eth_typing import (
Hash32,
from eth._utils.datatypes import (
Configurable,
)
from eth_utils import (
encode_hex,
ValidationError,
from eth.db.backends.base import (
BaseAtomicDB,
)

from eth.db.backends.base import BaseAtomicDB
from eth.exceptions import (
BlockNotFound,
)
from eth.validation import (
validate_word,
)

from eth._utils.datatypes import (
Configurable,
from eth_typing import (
Hash32,
)
from eth_utils import (
ValidationError,
encode_hex,
)

from eth2._utils.ssz import (
validate_imported_block_unchanged,
)

from eth2.beacon.db.chain import ( # noqa: F401
from eth2.beacon.db.chain import (
BaseBeaconChainDB,
BeaconChainDB,
)
from eth2.beacon.exceptions import (
BlockClassError,
StateMachineNotFound,
)
from eth2.beacon.state_machines.base import BaseBeaconStateMachine # noqa: F401
from eth2.beacon.types.blocks import (
BaseBeaconBlock,
)
from eth2.beacon.types.states import BeaconState
from eth2.beacon.types.states import (
BeaconState,
)
from eth2.beacon.typing import (
FromBlockParams,
Slot,
Expand All @@ -53,14 +54,19 @@
validate_slot,
)

if TYPE_CHECKING:
from eth2.beacon.state_machines.base import ( # noqa: F401
BaseBeaconStateMachine,
)


class BaseBeaconChain(Configurable, ABC):
"""
The base class for all BeaconChain objects
"""
chaindb = None # type: BaseBeaconChainDB
chaindb_class = None # type: Type[BaseBeaconChainDB]
sm_configuration = None # type: Tuple[Tuple[int, Type[BaseBeaconStateMachine]], ...]
sm_configuration = None # type: Tuple[Tuple[Slot, Type[BaseBeaconStateMachine]], ...]
chain_id = None # type: int

#
Expand Down
43 changes: 43 additions & 0 deletions eth2/beacon/chains/testnet/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from typing import (
TYPE_CHECKING,
)
from eth2.beacon.chains.base import (
BeaconChain,
)
from eth2.beacon.state_machines.forks.xiao_long_bao import (
XiaoLongBaoStateMachine,
)
from .constants import (
TESTNET_CHAIN_ID,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move it after from eth2.beacon.state_machines.forks.serenity.configs import ....

from eth2.beacon.state_machines.forks.serenity.configs import (
SERENITY_CONFIG,
)


if TYPE_CHECKING:
from eth2.beacon.typing import ( # noqa: F401
Slot,
)
from eth2.beacon.state_machines.base import ( # noqa: F401
BaseBeaconStateMachine,
)
from typing import ( # noqa: F401
Tuple,
Type,
)


TESTNET_SM_CONFIGURATION = (
# FIXME: Shouldn't access GENESIS_SLOT from a particular state machine configs.
(SERENITY_CONFIG.GENESIS_SLOT, XiaoLongBaoStateMachine),
) # type: Tuple[Tuple[Slot, Type[BaseBeaconStateMachine]], ...]


class BaseTestnetChain:
sm_configuration = TESTNET_SM_CONFIGURATION
chain_id = TESTNET_CHAIN_ID


class TestnetChain(BaseTestnetChain, BeaconChain):
pass
3 changes: 3 additions & 0 deletions eth2/beacon/chains/testnet/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@


TESTNET_CHAIN_ID = 5566
40 changes: 40 additions & 0 deletions eth2/beacon/state_machines/forks/xiao_long_bao/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from eth2.beacon.state_machines.base import (
BeaconStateMachine,
)
from eth2.beacon.state_machines.forks.serenity.blocks import (
SerenityBeaconBlock,
create_serenity_block_from_parent,
)
from eth2.beacon.state_machines.forks.serenity.state_transitions import (
SerenityStateTransition,
)
from eth2.beacon.state_machines.forks.serenity.states import (
SerenityBeaconState,
)
from eth2.beacon.types.blocks import (
BaseBeaconBlock,
)
from eth2.beacon.typing import (
FromBlockParams,
)

from .configs import (
XIAO_LONG_BAO_CONFIG,
)


class XiaoLongBaoStateMachine(BeaconStateMachine):
# fork name
fork = 'xiao_long_bao'

# classes
block_class = SerenityBeaconBlock
state_class = SerenityBeaconState
state_transition_class = SerenityStateTransition
config = XIAO_LONG_BAO_CONFIG

# methods
@staticmethod
def create_block_from_parent(parent_block: BaseBeaconBlock,
block_params: FromBlockParams) -> BaseBeaconBlock:
return create_serenity_block_from_parent(parent_block, block_params)
17 changes: 17 additions & 0 deletions eth2/beacon/state_machines/forks/xiao_long_bao/configs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from eth2.beacon.helpers import (
slot_to_epoch,
)
from eth2.beacon.state_machines.forks.serenity.configs import (
SERENITY_CONFIG,
)


SLOTS_PER_EPOCH = 4

XIAO_LONG_BAO_CONFIG = SERENITY_CONFIG._replace(
ChihChengLiang marked this conversation as resolved.
Show resolved Hide resolved
SLOTS_PER_EPOCH=SLOTS_PER_EPOCH,
GENESIS_EPOCH=slot_to_epoch(SERENITY_CONFIG.GENESIS_SLOT, SLOTS_PER_EPOCH),
TARGET_COMMITTEE_SIZE=2,
SHARD_COUNT=2,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With SLOTS_PER_EPOCH == 4, TARGET_COMMITTEE_SIZE == 2 and SHARD_COUNT == 2, does this mean we need at least 16 validators?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if I understand, do we need to specify 16 validators somewhere?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah just that in #465 we use 8 validators. Not a problem. Ignore me. 😅

MIN_ATTESTATION_INCLUSION_DELAY=2,
)
1 change: 1 addition & 0 deletions tests/core/p2p-proto/bcc/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def __init__(self, db: BaseAtomicDB) -> None:
coro_get_canonical_block_by_slot = async_passthrough('get_canonical_block_by_slot')
coro_get_canonical_block_root_by_slot = async_passthrough('get_canonical_block_root_by_slot')
coro_get_canonical_head = async_passthrough('get_canonical_head')
coro_get_canonical_head_root = async_passthrough('get_canonical_head_root')
coro_get_finalized_head = async_passthrough('get_finalized_head')
coro_get_block_by_root = async_passthrough('get_block_by_root')
coro_get_score = async_passthrough('get_score')
Expand Down
13 changes: 13 additions & 0 deletions tests/eth2/beacon/chains/test_chains.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import pytest
from eth2.beacon.chains.testnet import TestnetChain


@pytest.mark.parametrize(
"chain_klass",
(
TestnetChain,
)
)
def test_chain_class_well_defined(chain_klass):
chain = chain_klass(None)
assert chain.sm_configuration is not ()
ChihChengLiang marked this conversation as resolved.
Show resolved Hide resolved
13 changes: 13 additions & 0 deletions tests/eth2/beacon/state_machines/forks/test_fork_classes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import pytest
from eth2.beacon.state_machines.forks.xiao_long_bao import XiaoLongBaoStateMachine


@pytest.mark.parametrize(
"sm_klass",
(
XiaoLongBaoStateMachine,
Copy link
Contributor

@hwwhww hwwhww Apr 18, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about adding SerenityStateMachine? Would it pass the test?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It passes the test.

)
)
def test_sm_class_well_defined(sm_klass):
state_machine = sm_klass(chaindb=None, block=None)
assert state_machine.get_block_class()
5 changes: 5 additions & 0 deletions trinity/db/beacon/chain.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ async def coro_get_canonical_block_root_by_slot(self, slot: int) -> Hash32:
async def coro_get_canonical_head(self, block_class: Type[BaseBeaconBlock]) -> BaseBeaconBlock:
pass

@abstractmethod
async def coro_get_canonical_head_root(self)-> Hash32:
pass

@abstractmethod
async def coro_get_finalized_head(self, block_class: Type[BaseBeaconBlock]) -> BaseBeaconBlock:
pass
Expand Down Expand Up @@ -124,6 +128,7 @@ class AsyncBeaconChainDBPreProxy(BaseAsyncBeaconChainDB):
coro_get_canonical_block_by_slot = async_method('get_canonical_block_by_slot')
coro_get_canonical_block_root_by_slot = async_method('get_canonical_block_root_by_slot')
coro_get_canonical_head = async_method('get_canonical_head')
coro_get_canonical_head_root = async_method('get_canonical_head_root')
coro_get_finalized_head = async_method('get_finalized_head')
coro_get_block_by_root = async_method('get_block_by_root')
coro_get_score = async_method('get_score')
Expand Down