-
Notifications
You must be signed in to change notification settings - Fork 87
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
Support V3 transactions in the Contract
class
#1262
Support V3 transactions in the Contract
class
#1262
Conversation
Regarding the refactor, splitting the code into files may not look perfect. It's tough to optimally split these closely tied classes without stumbling into circular import issues. If this refactoring doesn't make sense or complicates the review, let me know so I will revert these changes. |
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## development #1262 +/- ##
===============================================
- Coverage 98.00% 89.43% -8.58%
===============================================
Files 89 90 +1
Lines 4522 4582 +60
===============================================
- Hits 4432 4098 -334
- Misses 90 484 +394
|
max_fee=max_fee, nonce=nonce, auto_estimate=auto_estimate | ||
) | ||
|
||
def prepare_invoke_v3( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm aware of the fact that we agreed to use postfixes. I do wonder, however, if in this particular case, where (prepare)_invoke(v1 | v3) can be differed by max_fee/resource_bounds and this is a helper class, would it make sense to have one prepare_invoke and one invoke, that takes those values as Union and based on type it prepares/makes v1 or v3 tx? wdyt? I know it may look like breaking existing approach to interface, but I do wonder if it does make sense in a helper class
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I definitely don't like the current interface. However, setting a fee as Union
may not be the best approach:
- A unified name for
max_fee
andl1_resource_bounds
would be required, let's say justfee
. While this could make sense for a user with plenty of context, it might be confusing in general - Thinking long term we will need to incorporate other V3 fields such as
l2_resource_bounds
,tip
etc. As a result, we would need to alter this interface again
One potential solution is to create InvokeV1Params
and InvokeV3Params
and then use
prepare_invoke(params: InvokeParams)
However, this approach will break consistency with other parts of our codebase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, it was just a rough idea either way. We can leave this as is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
starknet_py/net/contract/contract.py
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move all Contract related classes to the starknet_py/net/contract directory
Why this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to improve file organization. I would prefer to move it to starknet_py/contract
, but considering that we already have starknet_py/net/account
in place, I think it makes sense to keep contract directory in starknet_py/net
as well.
After all, I decided to rollback the refactoring changes. This decision was driven by the user perspective, where it only created needless confusion. For instance, |
@property | ||
def get_account(self): | ||
if self._account is not None: | ||
return self._account | ||
|
||
raise ValueError( | ||
"The account is not defined. It is not possible to send an invoke transaction." | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Do we really want to expose account there? It like a bit confusing property to have in
PreparedFunctionInvokeVX
, since it's only used as an internal helper and user would probably be aware which account they used to create prepared invoke anyway. - Also, could we maybe make
_account
non-optional? We can check whether it'sNone
inprepare_invoke_vX
before creating instancePreparedFunctionInvokeVX
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- The main motivation here is to avoid pyright errors when using
_account
. We are sure that it isn'tNone
, as we make this verification in__post_init__
(excluding cases where a user might change it manually on an existingPreparedFunctionInvokeVX
instance). Considering that an account is a prerequisite for transaction invocation, it kind of makes sense to have such a property inPreparedFunctionInvoke
. As an alternative, I could make_get_account
internal. - The
account
in theContract
class might beNone
, resulting in a None when calling prepare_invoke_vX. We can potentially make this assertion there, but then we would need to add this in four places instead of just one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As an alternative, I could make _get_account internal.
That is one solution, because it's overly clear what it does in the context of PreparedFunctionInvokeVX
We can potentially make this assertion there, but then we would need to add this in four places instead of just one.
More like 4 instead of 2. Also, can we maybe check _account
right away when it's passed to constructor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More like 4 instead of 2
It is implemented now only within the abstract PreparedFunctionInvoke
class
can we maybe check _account right away when it's passed to constructor?
This is a dataclass
, so the only option is __post_init__
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm 🔥
Related to #1235
Initial PR #1255
Introduced changes
PreparedFunctionCall
class:PreparedFunctionCall
has only methodscall()
andcall_raw()
PreparedFunctionInvoke
and derive from itPreparedFunctionInvokeV1
andPreparedFunctionInvokeV3
with methodsinvoke()
andestimate_fee()
Contract
class:declare()
into:declare_v1()
,declare_v2()
anddeclare_v3()
deploy_contract()
into:deploy_contract_v1()
,deploy_contract_v3()
and addsalt
andunique
parametersContractFunction
class:prepare()
into:prepare_invoke_v1()
,prepare_invoke_v3()
andprepare_call()
invoke()
into:invoke_v1()
andinvoke_v3()
DeclareResult
class:deploy()
into:deploy_v1()
anddeploy_v3()
MoveSentTransaction
class tosent_transaction.py
MoveContractFunction
,ContractData
,InvokeResult
and prepared call/invoke related classes tocontract_function.py
contract_utils.py
fileMove allContract
related classes to thestarknet_py/net/contract
directoryPlease note that documentation update and support for
Account.deploy_account()
will be addressed in separate PRs.