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

Add arg to take Unix integer as genesis time #686

Merged
merged 4 commits into from
Jun 4, 2019
Merged
Show file tree
Hide file tree
Changes from 3 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
11 changes: 9 additions & 2 deletions eth2/beacon/scripts/run_beacon_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ def cmd(self) -> str:
"trinity-beacon",
f"--port={self.port}",
f"--trinity-root-dir={self.root_dir}",
f" --beacon-nodekey={remove_0x_prefix(self.node_privkey.to_hex())}",
f"--beacon-nodekey={remove_0x_prefix(self.node_privkey.to_hex())}",
"-l debug",
]
if len(self.bootstrap_nodes) != 0:
Expand Down Expand Up @@ -187,6 +187,7 @@ def _record_happenning_logs(self, from_stream: str, line: str) -> None:
async def main():
num_validators = 5
time_bob_wait_for_alice = 15
genesis_delay = time_bob_wait_for_alice * 3

proc = await run(
f"rm -rf {Node.dir_root}"
Expand All @@ -198,7 +199,13 @@ async def main():
await proc.wait()

proc = await run(
f"trinity-beacon testnet --num={num_validators} --network-dir={Node.dir_root}"
" ".join((
"trinity-beacon",
"testnet",
f"--num={num_validators}",
f"--network-dir={Node.dir_root}",
f"--genesis-delay={genesis_delay}",
))
)
await proc.wait()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
@pytest.mark.parametrize(
'command',
(
('trinity-beacon', 'testnet', "--num=5"),
('trinity-beacon', 'testnet', "--num=1", "--genesis-delay=10"),
('trinity-beacon', 'testnet', "--num=1", "--genesis-time=1559315137"),
)
)
@pytest.mark.asyncio
Expand Down
52 changes: 43 additions & 9 deletions trinity/plugins/eth2/network_generator/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@
import time
from typing import (
Any,
Callable,
Dict,
Tuple,
)

from eth_utils import (
humanize_seconds,
)
from ruamel.yaml import (
YAML,
)
Expand Down Expand Up @@ -76,6 +80,18 @@ def __init__(self, name: str, root_dir: Path) -> None:
self.validator_keys_dir = self.client_dir / VALIDATOR_KEY_DIR


def get_genesis_time_from_constant(genesis_time: Timestamp) -> Callable[[], Timestamp]:
def get_genesis_time() -> Timestamp:
return genesis_time
return get_genesis_time


def get_genesis_time_from_delay(genesis_delay: Second)-> Callable[[], Timestamp]:
def get_genesis_time() -> Timestamp:
return Timestamp(int(time.time()) + genesis_delay)
return get_genesis_time


class NetworkGeneratorPlugin(BaseMainProcessPlugin):
@property
def name(self) -> str:
Expand All @@ -100,11 +116,19 @@ def configure_parser(cls, arg_parser: ArgumentParser, subparser: _SubParsersActi
type=int,
default=100,
)
testnet_generator_parser.add_argument(

genesis_time_group = testnet_generator_parser.add_mutually_exclusive_group(
required=True,
)
genesis_time_group.add_argument(
"--genesis-delay",
Copy link
Member

Choose a reason for hiding this comment

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

You could probably simplify this by changing this to simply compute what the equivalent would be in --genesis-time and to have it populate that value onto genesis_time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, the description "Seconds before genesis time from now" should be changed to "Set seconds delay after the genesis state is created as genesis time".
Since the usage of --genesis-delay option is for debugging, and the genesis state takes a long time to create, the "delay" actually starts after the latter is done. So for example when debugging in eth2/beacon/scripts/run_beacon_nodes.py, the choice of delay can be independent of the time to create the genesis state.

help="Seconds before genesis time from now",
help="Set seconds delay after the genesis state is created as genesis time",
type=int,
)
genesis_time_group.add_argument(
"--genesis-time",
help="Set a genesis time as Unix int, e.g. 1559292765",
type=int,
default=60,
)

testnet_generator_parser.set_defaults(func=cls.run_generate_testnet_dir)
Expand All @@ -115,12 +139,19 @@ def run_generate_testnet_dir(cls, args: Namespace, trinity_config: TrinityConfig
logger.info("Generating testnet")
network_dir = args.network_dir
if len(os.listdir(network_dir)) > 0:
logger.error("This directory is not empty, won't create network files here.")
logger.error("This directory is not empty, won't create network files here")
sys.exit(1)

clients = cls.generate_trinity_root_dirs(network_dir)
keymap = cls.generate_keys(args.num, network_dir, clients)
cls.generate_genesis_state(args.genesis_delay, network_dir, keymap, clients)

get_genesis_time = (
get_genesis_time_from_constant(args.genesis_time)
if args.genesis_time is not None
else get_genesis_time_from_delay(args.genesis_delay)
)
ChihChengLiang marked this conversation as resolved.
Show resolved Hide resolved

cls.generate_genesis_state(get_genesis_time, network_dir, keymap, clients)

logger.info(bold_green("Network generation completed"))

Expand All @@ -130,7 +161,7 @@ def generate_keys(cls,
network_dir: Path,
clients: Tuple[Client, ...]) -> Dict[Any, Any]:
logger = cls.get_logger()
logger.info(f"Creating {num} validators' keys")
logger.info("Creating %s validators' keys", num)
keys_dir = network_dir / KEYS_DIR
ChihChengLiang marked this conversation as resolved.
Show resolved Hide resolved
keys_dir.mkdir()

Expand All @@ -156,7 +187,7 @@ def generate_keys(cls,

@classmethod
def generate_genesis_state(cls,
genesis_delay: Second,
get_genesis_time: Callable[[], Timestamp],
Copy link
Member

Choose a reason for hiding this comment

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

Reviewing this a second time I'm a little confused by this API. Can you explain why we don't/can't just pass in a firm timestamp?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There are two possibilities for get_genesis_time: the one produced with get_genesis_time_from_constant()and the other by get_genesis_time_from_delay(). The reason to have a get_genesis_time interface is beacause for the latter case, the genesis time is determined after the create_mock_genesis finished.

An alternative could be

def generate_genesis_state(..., genesis_time, genesis_delay=None):
    state, _ = create_mock_genesis(
            ...
            genesis_time=genesis_time if genesis_time is not None else 0,
        )
    if genesis_delay is not None:
        state = state.copy(genesis_time=Timestamp(int(time.time()) + genesis_delay))
    ...

network_dir: Path,
keymap: Dict[Any, Any],
clients: Tuple[Client, ...]) -> None:
Expand All @@ -172,8 +203,11 @@ def generate_genesis_state(cls,
genesis_block_class=state_machine_class.block_class,
genesis_time=dummy_time,
)
logger.info(f"Genesis time will be {genesis_delay} seconds from now")
genesis_time = Timestamp(int(time.time()) + genesis_delay)
genesis_time = get_genesis_time()
logger.info(
ChihChengLiang marked this conversation as resolved.
Show resolved Hide resolved
"Genesis time will be %s from now",
humanize_seconds(genesis_time - int(time.time())),
)
state = state.copy(
genesis_time=genesis_time,
)
Expand Down