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

Reworked deploy and declare #573

Merged
merged 24 commits into from
Aug 9, 2022
Merged
Show file tree
Hide file tree
Changes from 18 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
29 changes: 17 additions & 12 deletions protostar/commands/declare/declare_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
class DeclareCommand(Command):
def __init__(
self,
gateway_facade: GatewayFacade,
gateway_facade_builder: GatewayFacade.Builder,
logger: Logger,
):
self._gateway_facade = gateway_facade
self._gateway_facade_builder = gateway_facade_builder
self._logger = logger

@property
Expand Down Expand Up @@ -46,30 +46,32 @@ def arguments(self) -> List[Command.Argument]:
Command.Argument(
name="signature",
description=("Signature information for the declaration."),
type="str",
type="int",
is_array=True,
),
Command.Argument(
name="token",
description="Used for declaring contracts in Alpha MainNet.",
type="str",
),
DeployCommand.wait_for_acceptance_arg,
DeployCommand.gateway_url_arg,
DeployCommand.network_arg,
]

async def run(self, args) -> SuccessfulDeclareResponse:
assert isinstance(args.contract, Path)
assert args.network is None or isinstance(args.network, str)
assert args.gateway_url is None or isinstance(args.gateway_url, str)
assert args.network is None or isinstance(args.network, str)
assert args.token is None or isinstance(args.token, str)
assert isinstance(args.wait_for_acceptance, bool)
assert args.signature is None or isinstance(args.signature, list)

return await self.declare(
compiled_contract_path=args.contract,
network=args.network,
gateway_url=args.gateway_url,
network=args.network or args.gateway_url,
token=args.token,
wait_for_acceptance=args.wait_for_acceptance,
signature=args.signature,
)

Expand All @@ -78,21 +80,24 @@ async def declare(
self,
compiled_contract_path: Path,
network: Optional[str] = None,
gateway_url: Optional[str] = None,
token: Optional[str] = None,
signature: Optional[List[str]] = None,
wait_for_acceptance: bool = False,
signature: Optional[List[int]] = None,
) -> SuccessfulDeclareResponse:
if network is None and gateway_url is None:
if network is None:
raise ProtostarException(
f"Argument `{DeployCommand.gateway_url_arg.name}` or `{DeployCommand.network_arg.name}` is required"
)

network_config = NetworkConfig.build(network=network, gateway_url=gateway_url)
self._gateway_facade_builder.set_network(network)
gateway_facade = self._gateway_facade_builder.build()

network_config = NetworkConfig(network)

response = await self._gateway_facade.declare(
response = await gateway_facade.declare(
compiled_contract_path=compiled_contract_path,
gateway_url=network_config.gateway_url,
token=token,
wait_for_acceptance=wait_for_acceptance,
signature=signature,
)

Expand Down
31 changes: 21 additions & 10 deletions protostar/commands/deploy/deploy_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,19 @@ class DeployCommand(Command):
type="str",
)

wait_for_acceptance_arg = Command.Argument(
name="wait-for-acceptance",
description="Waits for transaction to be accepted on chain.",
type="bool",
default=False,
)

def __init__(
self,
gateway_facade: GatewayFacade,
gateway_facade_builder: GatewayFacade.Builder,
logger: Logger,
) -> None:
self._gateway_facade = gateway_facade
self._gateway_facade_builder = gateway_facade_builder
self._logger = logger

@property
Expand Down Expand Up @@ -75,10 +82,11 @@ def arguments(self) -> List[Command.Argument]:
# pylint: disable=line-too-long
"[Read more about representing Cairo data types in the CLI.](https://www.cairo-lang.org/docs/hello_starknet/more_features.html#array-arguments-in-calldata)"
),
type="str",
type="int",
is_array=True,
),
Command.Argument(
# Note: This will be removed with the mainnet whitelist
name="token",
description="Used for deploying contracts in Alpha MainNet.",
type="str",
Expand All @@ -91,28 +99,31 @@ def arguments(self) -> List[Command.Argument]:
"of contract, salt and caller. "
"If the salt is not supplied, the contract will be deployed with a random salt."
),
type="str",
type="int",
),
DeployCommand.wait_for_acceptance_arg,
DeployCommand.gateway_url_arg,
DeployCommand.network_arg,
]

async def run(self, args):
if args.network is None and args.gateway_url is None:
network = args.network or args.gateway_url
if network is None:
raise ProtostarException(
f"Argument `{DeployCommand.gateway_url_arg.name}` or `{DeployCommand.network_arg.name}` is required"
)

network_config = NetworkConfig.build(
network=args.network, gateway_url=args.gateway_url
)
network_config = NetworkConfig(network)

self._gateway_facade_builder.set_network(network)
gateway_facade = self._gateway_facade_builder.build()

response = await self._gateway_facade.deploy(
response = await gateway_facade.deploy(
compiled_contract_path=args.contract,
gateway_url=network_config.gateway_url,
inputs=args.inputs,
token=args.token,
salt=args.salt,
wait_for_acceptance=args.wait_for_acceptance,
)

explorer_url = network_config.get_contract_explorer_url(response.address)
Expand Down
40 changes: 8 additions & 32 deletions protostar/commands/migrate/migrate_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
from protostar.commands.test.test_environment_exceptions import CheatcodeException
from protostar.migrator import Migrator
from protostar.protostar_exception import ProtostarException
from protostar.starknet_gateway import NetworkConfig
from protostar.utils.input_requester import InputRequester
from protostar.utils.log_color_provider import LogColorProvider
from protostar.commands.deploy import DeployCommand


class MigrateCommand(Command):
Expand Down Expand Up @@ -65,35 +65,15 @@ def arguments(self) -> List[Command.Argument]:
description="Skip confirming building the project.",
type="bool",
),
Command.Argument(
name=MigrateCommand.GATEWAY_URL_ARG_NAME,
description="The URL of a StarkNet gateway. It is required unless `--network` is provided.",
type="str",
),
Command.Argument(
name=MigrateCommand.NETWORK_ARG_NAME,
short_name="n",
description=(
"\n".join(
[
"The name of the StarkNet network.",
"It is required unless `--gateway-url` is provided.",
"",
"Supported StarkNet networks:",
]
+ [f"- `{n}`" for n in NetworkConfig.get_starknet_networks()]
)
),
type="str",
),
DeployCommand.gateway_url_arg,
DeployCommand.network_arg,
]

async def run(self, args):
await self.migrate(
migration_file_path=args.path,
rollback=args.rollback,
gateway_url=args.gateway_url,
network=args.network,
network=args.network or args.gateway_url,
output_dir_path=args.output_dir,
no_confirm=args.no_confirm,
)
Expand All @@ -103,18 +83,15 @@ async def migrate(
self,
migration_file_path: Path,
rollback: bool,
gateway_url: Optional[str],
network: Optional[str],
output_dir_path: Optional[Path],
no_confirm: bool,
):
if network is None and gateway_url is None:
if network is None:
raise ProtostarException(
f"Argument `{MigrateCommand.GATEWAY_URL_ARG_NAME}` or `{MigrateCommand.NETWORK_ARG_NAME}` is required"
)

network_config = NetworkConfig.build(gateway_url, network)

# mitigates the risk of running migrate on an outdated project
should_confirm = not no_confirm
if should_confirm and not self._requester.confirm(
Expand All @@ -126,10 +103,9 @@ async def migrate(

self._migrator_builder.set_logger(self._logger, self._log_color_provider)

migrator = await self._migrator_builder.build(
migration_file_path,
config=Migrator.Config(gateway_url=network_config.gateway_url),
)
self._migrator_builder.set_network(network)

migrator = await self._migrator_builder.build(migration_file_path)

try:
migrator_history = await migrator.run(rollback)
Expand Down
6 changes: 2 additions & 4 deletions protostar/commands/migrate/migrate_command_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ def setup_migrate(mocker: MockerFixture):

async def migrate(no_confirm: bool):
await migrate_command.migrate(
gateway_url="http://localhost:3000/",
network=None,
network="http://localhost:3000/",
migration_file_path=Path(),
rollback=False,
output_dir_path=None,
Expand All @@ -67,8 +66,7 @@ async def test_cheatcode_exceptions_are_pretty_printed(mocker: MockerFixture):

with pytest.raises(ProtostarException, match="CHEATCODE_EX_MSG"):
await migrate_command.migrate(
gateway_url="http://localhost:3000/",
network=None,
network="http://localhost:3000/",
migration_file_path=Path(),
rollback=False,
output_dir_path=None,
Expand Down
1 change: 1 addition & 0 deletions protostar/commands/test/cheatcodes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from .expect_revert_cheatcode import ExpectRevertCheatcode
from .given_cheatcode import GivenCheatcode
from .mock_call_cheatcode import MockCallCheatcode
from .network_config import CheatcodeNetworkConfig, get_default_network_config
from .prepare_cheatcode import PrepareCheatcode, PreparedContract
from .reflect_cheatcode import ReflectCheatcode
from .reject_cheatcode import RejectCheatcode
Expand Down
21 changes: 19 additions & 2 deletions protostar/commands/test/cheatcodes/declare_cheatcode.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import asyncio
from dataclasses import dataclass
from pathlib import Path
from typing import Optional

from starkware.python.utils import from_bytes
from starkware.starknet.business_logic.internal_transaction import InternalDeclare
Expand All @@ -11,6 +12,11 @@

from protostar.starknet.cheatcode import Cheatcode
from protostar.utils.starknet_compilation import StarknetCompiler
from protostar.commands.test.test_environment_exceptions import (
KeywordOnlyArgumentCheatcodeException,
)

from protostar.commands.test.cheatcodes.network_config import CheatcodeNetworkConfig


@dataclass
Expand All @@ -19,7 +25,9 @@ class DeclaredContract:


class DeclareCheatcodeProtocol(Protocol):
def __call__(self, contract_path_str: str) -> DeclaredContract:
def __call__(
self, contract_path_str: str, *args, config: Optional[CheatcodeNetworkConfig]
) -> DeclaredContract:
...


Expand All @@ -39,7 +47,16 @@ def name(self) -> str:
def build(self) -> DeclareCheatcodeProtocol:
return self.declare

def declare(self, contract_path_str: str) -> DeclaredContract:
def declare(
self,
contract_path_str: str,
*args,
# pylint: disable=unused-argument
config: Optional[CheatcodeNetworkConfig] = None,
) -> DeclaredContract:
if len(args) > 0:
raise KeywordOnlyArgumentCheatcodeException(self.name, ["config"])

declared_class = asyncio.run(self._declare_contract(Path(contract_path_str)))
assert declared_class
class_hash = declared_class.class_hash
Expand Down
17 changes: 15 additions & 2 deletions protostar/commands/test/cheatcodes/deploy_cheatcode.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import asyncio
from dataclasses import dataclass
from typing import Any, Callable, List
from typing import Any, Callable, List, Optional

from starkware.python.utils import to_bytes
from starkware.starknet.business_logic.execution.objects import CallInfo
from starkware.starknet.core.os.syscall_utils import initialize_contract_state

from protostar.commands.test.cheatcodes.prepare_cheatcode import PreparedContract
from protostar.starknet.cheatcode import Cheatcode
from protostar.commands.test.test_environment_exceptions import (
KeywordOnlyArgumentCheatcodeException,
)

from protostar.commands.test.cheatcodes.network_config import CheatcodeNetworkConfig


@dataclass(frozen=True)
Expand All @@ -32,7 +37,15 @@ def name(self) -> str:
def build(self) -> Callable[[Any], Any]:
return self.deploy_prepared

def deploy_prepared(self, prepared: PreparedContract):
def deploy_prepared(
self,
prepared: PreparedContract,
*args,
# pylint: disable=unused-argument
config: Optional[CheatcodeNetworkConfig] = None,
):
if len(args) > 0:
raise KeywordOnlyArgumentCheatcodeException(self.name, ["config"])
class_hash_bytes = to_bytes(prepared.class_hash)
future = asyncio.run_coroutine_threadsafe(
coro=initialize_contract_state(
Expand Down
16 changes: 16 additions & 0 deletions protostar/commands/test/cheatcodes/deploy_contract_cheatcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,22 @@
from protostar.commands.test.cheatcodes.prepare_cheatcode import PrepareCheatcode
from protostar.starknet.cheatcode import Cheatcode
from protostar.utils.data_transformer import CairoOrPythonData
from protostar.commands.test.test_environment_exceptions import (
KeywordOnlyArgumentCheatcodeException,
)

from protostar.commands.test.cheatcodes.network_config import CheatcodeNetworkConfig


class DeployContractCheatcodeProtocol(Protocol):
# pylint bug ?
# pylint: disable=keyword-arg-before-vararg
def __call__(
self,
contract_path: str,
constructor_args: Optional[CairoOrPythonData] = None,
*args,
config: Optional[CheatcodeNetworkConfig],
) -> DeployedContract:
...

Expand All @@ -41,11 +50,18 @@ def name(self) -> str:
def build(self) -> DeployContractCheatcodeProtocol:
return self.deploy_contract

# pylint bug ?
# pylint: disable=keyword-arg-before-vararg
def deploy_contract(
self,
contract_path: str,
constructor_args: Optional[CairoOrPythonData] = None,
*args,
# pylint: disable=unused-argument
config: Optional[CheatcodeNetworkConfig] = None,
) -> DeployedContract:
if len(args) > 0:
raise KeywordOnlyArgumentCheatcodeException(self.name, ["config"])
declared_contract = self._declare_cheatcode.declare(contract_path)
prepared_contract = self._prepare_cheatcode.prepare(
declared_contract, constructor_args
Expand Down
Loading