Skip to content

Commit

Permalink
Enable multisig for account (#1476)
Browse files Browse the repository at this point in the history
Time spent on this PR: 0.5

## Pull request type

Please check the type of change your PR introduces:

- [ ] Bugfix
- [x] Feature
- [ ] Code style update (formatting, renaming)
- [ ] Refactoring (no functional changes, no api changes)
- [ ] Build related changes
- [ ] Documentation content changes
- [ ] Other (please describe):

## What is the current behavior?

Not possible to use an Argent multisig account as account in the
scripts.

Resolves #1411

## What is the new behavior?

- `get_starknet_account` can handle an Argent multisig account as
sender.
- all invoke tx now use the same `execute_v1` function extracted from
`starknet-py`.
- this function can be lazy and batch execute calls afterwards instead
of executing them when called.
- also added cache of the class_hashes at compile step to speed up the
deployment script.

<!-- Reviewable:start -->
- - -
This change is [<img src="https://reviewable.io/review_button.svg"
height="34" align="absmiddle"
alt="Reviewable"/>](https://reviewable.io/reviews/kkrt-labs/kakarot/1476)
<!-- Reviewable:end -->
  • Loading branch information
ClementWalter authored Oct 9, 2024
1 parent 6f4005e commit 7a89bf9
Show file tree
Hide file tree
Showing 12 changed files with 313 additions and 180 deletions.
5 changes: 2 additions & 3 deletions .github/workflows/cairo-zero-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ on:
branches:
- main
pull_request:
paths:
- cairo_zero/**

branches:
- "*"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Expand Down
38 changes: 7 additions & 31 deletions deployments/starknet-sepolia/deployments.json
Original file line number Diff line number Diff line change
@@ -1,32 +1,8 @@
{
"kakarot": {
"address": "0x78bd079b79aa45111313f200a22e5c52ff7526c746d73b65672cc28acbe2263",
"tx": "0x897e9cb077b13aec370f1dae4807dffb324a621416023e4fd67c4eb1f8d2d3",
"artifact": "None"
},
"EVM": {
"address": "0x6ae512c704e2fafbc06e6a6401e9ce02d534aad4bc34400fc1d8d82e88be316",
"tx": "0x515788cd50f04984c5b5cd6c7f75014abbb0b7bdfe449b4c2d24dd6816db756",
"artifact": "None"
},
"Counter": {
"address": "0x2d6741b182475b7cfc62ec1000fbcba553ea08f2e603fa2840d0288cd2d1e3c",
"tx": "0xd1781094a55ac09c3177e6799f9d484c5477baa6d120923c942da5c2fdbfea",
"artifact": "build/fixtures/Counter.json"
},
"MockPragmaOracle": {
"address": "0x17e64c92b06da9a331da9fd333a683a33019ae2a393254caf332d4158edc74d",
"tx": "0x3d6b91602c1e290bc65c6f85751f5ea156cf982d01c6bf1ea694d7398a9d5a5",
"artifact": "build/ssj/contracts_MockPragmaOracle"
},
"UniversalLibraryCaller": {
"address": "0x4e23e34042e1f0198311e2dcfc9565c214a48261574f2b37a7f12d1f65100f1",
"tx": "0x3cdee93215396193d9e08e7be3dccc7f6a650ba35f6f57b8762a540ca117816",
"artifact": "cairo1_contracts/utils/target/dev/utils_UniversalLibraryCaller.contract_class.json"
},
"BenchmarkCairoCalls": {
"address": "0x6ea732a6102b65dc04b54ec35304d5f27d1c3fbc81fd6810bd90b126f2e0d11",
"tx": "0x1c5464c82da97a4e9aeb088da8e5a932e4b14204efb192fe7b81dabe327e2d2",
"artifact": "cairo1_contracts/utils/target/dev/utils_BenchmarkCairoCalls.contract_class.json"
}
}
"kakarot": "0x78bd079b79aa45111313f200a22e5c52ff7526c746d73b65672cc28acbe2263",
"EVM": "0x6ae512c704e2fafbc06e6a6401e9ce02d534aad4bc34400fc1d8d82e88be316",
"Counter": "0x2d6741b182475b7cfc62ec1000fbcba553ea08f2e603fa2840d0288cd2d1e3c",
"MockPragmaOracle": "0x17e64c92b06da9a331da9fd333a683a33019ae2a393254caf332d4158edc74d",
"UniversalLibraryCaller": "0x4e23e34042e1f0198311e2dcfc9565c214a48261574f2b37a7f12d1f65100f1",
"BenchmarkCairoCalls": "0x6ea732a6102b65dc04b54ec35304d5f27d1c3fbc81fd6810bd90b126f2e0d11"
}
2 changes: 1 addition & 1 deletion kakarot_scripts/benchmark_cairo_calls.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ async def main():
# %% Deploy contracts
cairo_contract = await deploy_starknet("BenchmarkCairoCalls")
cairo_contract_caller = await deploy_kakarot(
"CairoPrecompiles", "BenchmarkCairoCalls", cairo_contract["address"]
"CairoPrecompiles", "BenchmarkCairoCalls", cairo_contract
)
await invoke(
"kakarot",
Expand Down
12 changes: 10 additions & 2 deletions kakarot_scripts/compile_kakarot.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
import multiprocessing as mp
from datetime import datetime

from kakarot_scripts.constants import COMPILED_CONTRACTS, NETWORK
from kakarot_scripts.utils.starknet import compile_contract
from kakarot_scripts.constants import COMPILED_CONTRACTS, DECLARED_CONTRACTS, NETWORK
from kakarot_scripts.utils.starknet import (
compile_contract,
compute_deployed_class_hash,
dump_class_hashes,
)

mp.set_start_method("fork")

Expand All @@ -20,6 +24,10 @@ def main():
initial_time = datetime.now()
with mp.Pool() as pool:
pool.map(compile_contract, COMPILED_CONTRACTS)
logger.info("ℹ️ Computing deployed class hashes")
with mp.Pool() as pool:
class_hashes = pool.map(compute_deployed_class_hash, DECLARED_CONTRACTS)
dump_class_hashes(dict(zip(DECLARED_CONTRACTS, class_hashes)))

logger.info(
f"✅ Compiled all in {(datetime.now() - initial_time).total_seconds():.2f}s"
Expand Down
2 changes: 2 additions & 0 deletions kakarot_scripts/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class NetworkType(Enum):
"max_wait": 60,
"class_hash": 0x061DAC032F228ABEF9C6626F995015233097AE253A7F72D68552DB02F2971B8F,
"voyager_api_url": "https://api.voyager.online/beta",
"argent_multisig_api": "https://cloud.argent-api.com/v1/multisig/starknet/mainnet",
},
"sepolia": {
"name": "starknet-sepolia",
Expand All @@ -56,6 +57,7 @@ class NetworkType(Enum):
"max_wait": 20,
"class_hash": 0x061DAC032F228ABEF9C6626F995015233097AE253A7F72D68552DB02F2971B8F,
"voyager_api_url": "https://sepolia-api.voyager.online/beta",
"argent_multisig_api": "https://cloud.argent-api.com/v1/multisig/starknet/sepolia",
},
"starknet-devnet": {
"name": "starknet-devnet",
Expand Down
31 changes: 22 additions & 9 deletions kakarot_scripts/deploy_kakarot.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,17 @@
from kakarot_scripts.utils.starknet import (
dump_declarations,
dump_deployments,
execute_calls,
get_balance,
get_declarations,
)
from kakarot_scripts.utils.starknet import get_deployments as get_starknet_deployments
from kakarot_scripts.utils.starknet import get_starknet_account, invoke
from kakarot_scripts.utils.starknet import (
get_starknet_account,
invoke,
register_lazy_account,
remove_lazy_account,
)

logging.basicConfig()
logger = logging.getLogger(__name__)
Expand All @@ -47,6 +53,7 @@
async def main():
# %% Declarations
account = await get_starknet_account()
register_lazy_account(account.address)
logger.info(f"ℹ️ Using account 0x{account.address:064x} as deployer")
balance_pref = await get_balance(account.address)

Expand All @@ -71,7 +78,7 @@ async def main():
"EVM",
"set_coinbase",
COINBASE,
address=starknet_deployments["EVM"]["address"],
address=starknet_deployments["EVM"],
)
starknet_deployments["Counter"] = await deploy_starknet("Counter")
starknet_deployments["MockPragmaOracle"] = await deploy_starknet(
Expand All @@ -88,7 +95,7 @@ async def main():
if starknet_deployments.get("kakarot") and NETWORK["type"] is not NetworkType.DEV:
logger.info("ℹ️ Kakarot already deployed, checking version.")
deployed_class_hash = await RPC_CLIENT.get_class_hash_at(
starknet_deployments["kakarot"]["address"]
starknet_deployments["kakarot"]
)
if deployed_class_hash != class_hash["kakarot"]:
await invoke("kakarot", "upgrade", class_hash["kakarot"])
Expand Down Expand Up @@ -118,34 +125,40 @@ async def main():
"kakarot",
"set_base_fee",
DEFAULT_GAS_PRICE,
address=starknet_deployments["kakarot"]["address"],
address=starknet_deployments["kakarot"],
)

dump_deployments(starknet_deployments)

# %% Pre-EIP155 deployments
# Execute calls in lazy mode
# After this point, Kakarot needs to be deployed for the remaining calls to be executed
await execute_calls()
remove_lazy_account(account.address)

# %% EVM Deployments
evm_deployments = get_evm_deployments()
evm_deployments["Multicall3"] = await deploy_with_presigned_tx(

# %% Pre-EIP155 deployments, done only once
await deploy_with_presigned_tx(
MULTICALL3_DEPLOYER,
MULTICALL3_SIGNED_TX,
name="Multicall3",
max_fee=int(0.1e18),
)
evm_deployments["Arachnid_Proxy"] = await deploy_with_presigned_tx(
await deploy_with_presigned_tx(
ARACHNID_PROXY_DEPLOYER,
ARACHNID_PROXY_SIGNED_TX,
name="Arachnid Proxy",
max_fee=int(0.1e18),
)
evm_deployments["CreateX"] = await deploy_with_presigned_tx(
await deploy_with_presigned_tx(
CREATEX_DEPLOYER,
CREATEX_SIGNED_TX,
amount=0.3,
name="CreateX",
max_fee=int(0.2e18),
)

# %% EVM Deployments
if not EVM_ADDRESS:
logger.info("ℹ️ No EVM address provided, skipping EVM deployments")
return
Expand Down
65 changes: 38 additions & 27 deletions kakarot_scripts/utils/kakarot.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ def get_log_receipts(tx_receipt):
if WEB3.is_connected():
return tx_receipt.logs

kakarot_address = _get_starknet_deployments()["kakarot"]["address"]
kakarot_address = _get_starknet_deployments()["kakarot"]
kakarot_events = [
event
for event in tx_receipt.events
Expand Down Expand Up @@ -478,6 +478,14 @@ async def send_pre_eip155_transaction(
await _invoke_starknet(
"kakarot", "set_authorized_pre_eip155_tx", int(evm_address, 16), msg_hash
)
nonce = await _call_starknet(
"account_contract", "get_nonce", address=starknet_address
)
if nonce != 0:
logger.info(
f"ℹ️ Nonce for {evm_address} is not 0 ({nonce}), skipping transaction"
)
return

if WEB3.is_connected():
tx_hash = WEB3.eth.send_raw_transaction(signed_tx)
Expand All @@ -493,6 +501,7 @@ async def send_pre_eip155_transaction(
# Keypair not required for already signed txs
key_pair=KeyPair(int(0x10), 0x20),
)

return await send_starknet_transaction(
evm_account=sender_account,
signature_r=int.from_bytes(r, "big"),
Expand Down Expand Up @@ -604,33 +613,30 @@ async def send_starknet_transaction(
"execute_before": current_timestamp + 60 * 60,
}
max_fee = _max_fee if max_fee in [None, 0] else max_fee
response = (
await _get_starknet_contract(
"account_contract", address=evm_account.address, provider=relayer
)
.functions["execute_from_outside"]
.invoke_v1(
outside_execution=outside_execution,
call_array=[
{
"to": 0xDEAD,
"selector": 0xDEAD,
"data_offset": 0,
"data_len": len(packed_encoded_unsigned_tx),
}
],
calldata=list(packed_encoded_unsigned_tx),
signature=[
*int_to_uint256(signature_r),
*int_to_uint256(signature_s),
signature_v,
],
max_fee=max_fee,
)
tx_hash = await _invoke_starknet(
"account_contract",
"execute_from_outside",
outside_execution,
[
{
"to": 0xDEAD,
"selector": 0xDEAD,
"data_offset": 0,
"data_len": len(packed_encoded_unsigned_tx),
}
],
list(packed_encoded_unsigned_tx),
[
*int_to_uint256(signature_r),
*int_to_uint256(signature_s),
signature_v,
],
address=evm_account.address,
account=relayer,
)

await wait_for_transaction(tx_hash=response.hash)
receipt = await RPC_CLIENT.get_transaction_receipt(response.hash)
await wait_for_transaction(tx_hash=tx_hash)
receipt = await RPC_CLIENT.get_transaction_receipt(tx_hash)
transaction_events = [
event
for event in receipt.events
Expand Down Expand Up @@ -748,9 +754,14 @@ async def deploy_with_presigned_tx(
deployer_starknet_address = await deploy_and_fund_evm_address(
deployer_evm_address, amount
)
receipt, response, success, gas_used = await send_pre_eip155_transaction(
response = await send_pre_eip155_transaction(
deployer_evm_address, deployer_starknet_address, signed_tx, max_fee
)
if response is None:
logger.info("ℹ️ Transaction already executed")
return

receipt, response, success, gas_used = response
deployed_address = response[1]
logger.info(f"✅ {name} Deployed at: 0x{deployed_address:040x}")
deployed_starknet_address = await get_starknet_address(deployed_address)
Expand Down
Loading

0 comments on commit 7a89bf9

Please sign in to comment.