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

V3 transactions in outside execution tests for argent #1554

Open
wants to merge 3 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# asdf
.tool-versions

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down
125 changes: 100 additions & 25 deletions starknet_py/tests/e2e/account/outside_execution_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,49 @@
from starknet_py.constants import ANY_CALLER, OutsideExecutionInterfaceID
from starknet_py.hash.selector import get_selector_from_name
from starknet_py.net.account.account import BaseAccount
from starknet_py.net.client_models import Call, OutsideExecutionTimeBounds
from starknet_py.net.client_models import (
Call,
OutsideExecutionTimeBounds,
ResourceBounds,
)
from starknet_py.tests.e2e.fixtures.constants import MAX_FEE
from starknet_py.transaction_errors import TransactionRevertedError


@pytest.mark.asyncio
async def test_argent_account_outside_execution_compatibility(
argent_account: BaseAccount,
argent_account_v040: BaseAccount,
):
result = await argent_account.supports_interface(OutsideExecutionInterfaceID.V1)
assert result is True
result = await argent_account.supports_interface(OutsideExecutionInterfaceID.V2)
assert result is False

result = await argent_account_v040.supports_interface(
OutsideExecutionInterfaceID.V1
)
assert result is True
result = await argent_account_v040.supports_interface(
OutsideExecutionInterfaceID.V2
)
assert result is True
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could we change this test to be parametrized?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm afraid it's not trivial due to dependency injection. I attempted to reduce amount of statements. please check.



# TODO (#1546): Remove skip mark
@pytest.mark.skip
@pytest.mark.asyncio
async def test_account_outside_execution_any_caller(
argent_account: BaseAccount,
argent_account_v040: BaseAccount,
account: BaseAccount,
map_contract,
):

assert any(
[
await argent_account.supports_interface(OutsideExecutionInterfaceID.V1),
await argent_account.supports_interface(OutsideExecutionInterfaceID.V2),
await argent_account_v040.supports_interface(
OutsideExecutionInterfaceID.V1
),
await argent_account_v040.supports_interface(
OutsideExecutionInterfaceID.V2
),
]
)

Expand All @@ -41,7 +57,7 @@ async def test_account_outside_execution_any_caller(
calldata=[20, 20],
)

call = await argent_account.sign_outside_execution_call(
call = await argent_account_v040.sign_outside_execution_call(
calls=[
put_call,
],
Expand All @@ -52,60 +68,79 @@ async def test_account_outside_execution_any_caller(
caller=ANY_CALLER,
)

tx = await argent_account.execute_v1(calls=[call], max_fee=MAX_FEE)
await argent_account.client.wait_for_tx(tx.transaction_hash)
tx = await account.execute_v3(
calls=[call],
l1_resource_bounds=ResourceBounds(
max_amount=int(1e5), max_price_per_unit=int(1e13)
),
)
await account.client.wait_for_tx(tx.transaction_hash)


@pytest.mark.asyncio
async def test_account_outside_execution_for_invalid_caller(
argent_account: BaseAccount,
argent_account_v040: BaseAccount,
account: BaseAccount,
map_contract,
):
assert any(
[
await argent_account.supports_interface(OutsideExecutionInterfaceID.V1),
await argent_account.supports_interface(OutsideExecutionInterfaceID.V2),
await argent_account_v040.supports_interface(
OutsideExecutionInterfaceID.V1
),
await argent_account_v040.supports_interface(
OutsideExecutionInterfaceID.V2
),
]
)

random_address = 0x1234567890123456789012345678901234567890

put_call = Call(
to_addr=map_contract.address,
selector=get_selector_from_name("put"),
calldata=[20, 20],
)

call = await argent_account.sign_outside_execution_call(
call = await argent_account_v040.sign_outside_execution_call(
calls=[
put_call,
],
execution_time_bounds=OutsideExecutionTimeBounds(
execute_after=datetime.datetime.now() - datetime.timedelta(hours=1),
execute_before=datetime.datetime.now() + datetime.timedelta(hours=1),
),
caller=account.address,
caller=random_address,
)

tx = await argent_account.execute_v1(calls=[call], max_fee=MAX_FEE)
tx = await account.execute_v3(
calls=[call],
l1_resource_bounds=ResourceBounds(
max_amount=int(1e5), max_price_per_unit=int(1e13)
),
)

with pytest.raises(TransactionRevertedError) as err:
await argent_account.client.wait_for_tx(tx.transaction_hash)
await argent_account_v040.client.wait_for_tx(tx.transaction_hash)

assert "argent/invalid-caller" in err.value.message


# TODO (#1546): Remove skip mark
@pytest.mark.skip
@pytest.mark.asyncio
async def test_account_outside_execution_for_impossible_time_bounds(
argent_account: BaseAccount,
argent_account_v040: BaseAccount,
account: BaseAccount,
map_contract,
):

assert any(
[
await argent_account.supports_interface(OutsideExecutionInterfaceID.V1),
await argent_account.supports_interface(OutsideExecutionInterfaceID.V2),
await argent_account_v040.supports_interface(
OutsideExecutionInterfaceID.V1
),
await argent_account_v040.supports_interface(
OutsideExecutionInterfaceID.V2
),
]
)

Expand All @@ -115,7 +150,7 @@ async def test_account_outside_execution_for_impossible_time_bounds(
calldata=[20, 20],
)

call = await argent_account.sign_outside_execution_call(
call = await argent_account_v040.sign_outside_execution_call(
calls=[put_call],
execution_time_bounds=OutsideExecutionTimeBounds(
execute_after=datetime.datetime.now() - datetime.timedelta(days=10),
Expand All @@ -124,9 +159,49 @@ async def test_account_outside_execution_for_impossible_time_bounds(
caller=ANY_CALLER,
)

tx = await argent_account.execute_v1(calls=[call], max_fee=MAX_FEE)
tx = await account.execute_v1(calls=[call], max_fee=MAX_FEE)

with pytest.raises(TransactionRevertedError) as err:
await argent_account.client.wait_for_tx(tx.transaction_hash)
await argent_account_v040.client.wait_for_tx(tx.transaction_hash)

assert "argent/invalid-timestamp" in err.value.message


@pytest.mark.asyncio
async def test_account_outside_execution_by_itself_is_impossible(
argent_account_v040: BaseAccount,
map_contract,
):

assert any(
[
await argent_account_v040.supports_interface(
OutsideExecutionInterfaceID.V1
),
await argent_account_v040.supports_interface(
OutsideExecutionInterfaceID.V2
),
]
)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think yes. But I see your suggest. Removing.


put_call = Call(
to_addr=map_contract.address,
selector=get_selector_from_name("put"),
calldata=[20, 20],
)

call = await argent_account_v040.sign_outside_execution_call(
calls=[put_call],
execution_time_bounds=OutsideExecutionTimeBounds(
execute_after=datetime.datetime.now() - datetime.timedelta(days=10),
execute_before=datetime.datetime.now() - datetime.timedelta(days=9),
),
caller=ANY_CALLER,
)

tx = await argent_account_v040.execute_v1(calls=[call], max_fee=MAX_FEE)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please use execute_v3.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Huh! How did those sneak in?! Thank you for catching.


with pytest.raises(TransactionRevertedError) as err:
await argent_account_v040.client.wait_for_tx(tx.transaction_hash)

assert "ReentrancyGuard: reentrant call" in err.value.message
18 changes: 14 additions & 4 deletions starknet_py/tests/e2e/client/fixtures/transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,17 @@
from starknet_py.net.account.account import Account
from starknet_py.net.full_node_client import FullNodeClient
from starknet_py.net.models.transaction import DeployAccountV1
from starknet_py.net.signer.key_pair import KeyPair
from starknet_py.net.udc_deployer.deployer import Deployer
from starknet_py.tests.e2e.client.fixtures.prepare_net_for_gateway_test import (
PreparedNetworkData,
)
from starknet_py.tests.e2e.fixtures.constants import MAX_FEE
from starknet_py.tests.e2e.utils import (
get_deploy_account_details,
_get_random_private_key_unsafe,
get_deploy_account_transaction,
new_address,
prepay_account,
)


Expand All @@ -29,16 +32,23 @@ async def deploy_account_transaction(
"""
Returns a DeployAccount transaction
"""
key_pair = KeyPair.from_private_key(_get_random_private_key_unsafe())

address, key_pair, salt, class_hash = await get_deploy_account_details(
class_hash=account_with_validate_deploy_class_hash,
address, salt = new_address(
account_with_validate_deploy_class_hash,
[key_pair.public_key],
)

await prepay_account(
address=address,
eth_fee_contract=eth_fee_contract,
strk_fee_contract=strk_fee_contract,
)

return await get_deploy_account_transaction(
address=address,
key_pair=key_pair,
class_hash=class_hash,
class_hash=account_with_validate_deploy_class_hash,
salt=salt,
client=FullNodeClient(devnet),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
from starknet_py.net.client_models import TransactionFinalityStatus


# TODO (#1546): Remove skip mark
@pytest.mark.skip
@pytest.mark.asyncio
async def test_account_outside_execution_any_caller(
account,
argent_account,
argent_account_v040,
map_contract,
):
# pylint: disable=import-outside-toplevel,too-many-locals
Expand All @@ -35,7 +33,7 @@ async def test_account_outside_execution_any_caller(
# the specified caller. In this case, anyone will be able to execute it.

# Note that signing account does not need to have any funds to sign the transaction.
call = await argent_account.sign_outside_execution_call(
call = await argent_account_v040.sign_outside_execution_call(
calls=[
put_call,
],
Expand Down
Loading
Loading