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

feat(katana): starknet messaging L1-L2 and L2-L3 #914

Merged
merged 37 commits into from
Oct 2, 2023

Conversation

glihm
Copy link
Collaborator

@glihm glihm commented Sep 22, 2023

This is the rework for the messaging inside Katana.

L1-L2

To test L1-L2 messaging, Katana implements the same logic as the production sequencer: when a message is logged from L1 by the Starknet Core contract, this log is processed and a L1HandlerTransaction is fired internally.

In the case of testing as we are, the Starknet Core contract were slightly modified to directly register the message hash to be consumed (instead of waiting a block to be proven as it's one in production).

Remember, the messaging is totally asynchronous and asymmetric. If you send a message L1->L2, the log is consumed automatically by the sequencer, and the L1HandlerTransaction is fired automatically.
Howerver, sending a message L2->L1 sends actually only the hash of the message. Then you have to consume it manually.

L2-L3

By modifying a bit how the messaging works, Katana is now capable of communicating with Starknet. Which unlock the possibility of using Katana as a L3 with messaging features.

This modification is that, as the messaging is only accepting EthAddress as the to_address field of the message, we need to pass ContractAddress. To do so, the to_address field is reused to indicate Katana (L3) that we want to send a message, or if we want to execute a call on Starknet.

Yes, execute. Because in L1-L2 the messaging is asymmetric. But here, between L2 and an appchain, were costs are very low, Katana offers the possibility to directly execute a message on Starknet!

How to test the messaging

With some Makefile, it's easy to test the flow. But if you modify the contracts, then
you'll have to modify the files or directly use starkli or cast to interact with the chains.

Please ensure you have those tools installed before continuing:

  • scarb to build cairo contracts v0.7.0.
  • starkli to interact with Katana.
  • foundry to interact with Anvil.

If it's the first time you run the scripts, please go into crates/katana/core/contracts/messaging/solidity and run forge install.

L1-L2

# Terminal 1: spin up anvil.
anvil

# Terminal 2: spin up Katana loading the configuration to communicate with Ethereum.
./target/debug/katana --messaging crates/katana/core/contracts/messaging/anvil.messaging.json

# Terminal 3: change directory into the messaging contracts.
cd crates/katana/core/contracts/messaging

# Setup anvil with messaging Starknet Core contract and Contract1.sol.
make -sC ./solidity/ deploy

# Declare and deploy contract_msg_l1.cairo to have a contract on Katana to send messages.
make -sC ./cairo/ setup_for_l1_messaging

# Send message L1 -> L2 with a single value.
make -sC solidity/ send_msg selector_str=msg_handler_value payload="[123]"

# Send message L1 -> L2 with a serialized struct.
make -sC solidity/ send_msg selector_str=msg_handler_struct payload="[1,2]"

# Send message L2 -> L1 to be manually consumed.
make -sC cairo/ send_msg_value_l1 value=2

# Consume the message previously sent. You can try to call it two times and see the second one reverting.
make -sC solidity/ consume_msg payload="[2]"

L2-L3

In this example, we need two Katana. One for playing the role of Starknet, and an other one being a L3/appchain.

# Terminal 1, spin up a regular Katana to play starknet role on the default port `5050`.
katana

# Terminal 2, spin up a Katana being a L3/Appchain with messaging configured for Starknet on port `6060`.
./target/debug/katana --messaging crates/katana/core/contracts/messaging/l3.messaging.json -p 6060

# Terminal 3, change directory into the messaging contracts.
cd crates/katana/core/contracts/messaging

# Setup the Starknet Katana with `appchain_messaging` contract playing the same role as
# Starknet Core contract on L1 and a simple contract to send/receive messages.
make -sC ./cairo/ setup_l2_messaging

# Setup the appchain contract.
make -sC ./cairo/ setup_l3_messaging

# Send a message L3 -> L2 to be manually consumed.
make -sC ./cairo/ send_msg_value_l2 value=3

# Consume the message on L2 (it's a span, so length first).
make -sC ./cairo/ consume_msg_from_l3 payload="1 3"

# Send a message L3 -> L2 to be executed directly on L2.
make -sC ./cairo/ exec_msg_l2 selector_str=set_value value=2

# Verify the execution by getting the value.
make -sC ./cairo/ get_value_l2

# Send a message L2 -> L3.
# Try to change the value to see the transaction error.
make -sC cairo/ send_msg_l3 selector_str=msg_handler_value value=888

You can monitor Katana logs to see messages being settled on the settlement layer (eth or sn) and the L1HandlerTransaction being generated.

L1Handler transaction added to the pool:
|      tx_hash     | 0x3399b8ecdcfbf991d08932c30b26bdf460e8814a068ba89fb4754d3512f72e5
| contract_address | 0x429a64d97c1422a37a09fc7406f35c264be59b744aaff5a79d59393eb1bc7e1
|     selector     | 0x5421de947699472df434466845d68528f221a52fce7ad2934c5dae2e1f1cdc
|     calldata     | [0xe7f1725e7734ce288f8367e1bb143e90bb3f0512, 0x7b]

...

Message sent to settlement layer:
|     hash     | 0xc9ad27b9d1972f670643829152675cc46b19870f4aff78e1d14e61543969350a
| from_address | 0x517ececd29116499f4a1b64b094da79ba08dfd54a3edaa316134c41f8160973
|  to_address  | 0xe7f1725e7734ce288f8367e1bb143e90bb3f0512
|   payload    | [0x2]

@kariy as this feature is importing ether-rs which is a consequent library, do you think we need to do a messaging feature to be enabled/disabled? Or do we want the fully featured katana by default with messaging?

As always, thank you for every comment/feedback/review. 🙏

@glihm glihm changed the title feat(katana): starknet messaging L1-L2 and L2-Appchain feat(katana): starknet messaging L1-L2 and L2-L3 Sep 22, 2023
@glihm
Copy link
Collaborator Author

glihm commented Sep 22, 2023

With rust fmt, I have a strange behavior. Everytime I run it, I have new spaces on the lines indicated in red. Not sure how to fix it. I have to rework my indentation due to the escaped string?

Copy link
Member

@kariy kariy left a comment

Choose a reason for hiding this comment

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

initial review.. i've only been looking thru the Rust code for now, haven't yet looked into the contracts and test the whole flow.

i have some nitpicks but will leave that at the end and focus on the design for now

crates/katana/core/src/messaging/ethereum_messenger.rs Outdated Show resolved Hide resolved
crates/katana/core/src/messaging/mod.rs Outdated Show resolved Hide resolved
crates/katana/src/args.rs Outdated Show resolved Hide resolved
crates/katana/core/src/messaging/mod.rs Outdated Show resolved Hide resolved
crates/katana/core/src/messaging/mod.rs Outdated Show resolved Hide resolved
crates/katana/core/src/messaging/service.rs Outdated Show resolved Hide resolved
crates/katana/core/src/messaging/mod.rs Outdated Show resolved Hide resolved
crates/katana/core/src/messaging/starknet_messenger.rs Outdated Show resolved Hide resolved
crates/katana/core/src/messaging/service.rs Outdated Show resolved Hide resolved
crates/katana/core/src/messaging/service.rs Outdated Show resolved Hide resolved
@kariy
Copy link
Member

kariy commented Sep 25, 2023

do you think we need to do a messaging feature to be enabled/disabled?

personally, i prefer if can have it under a feature

kariy and others added 10 commits September 30, 2023 04:00
unit test focus on core function to parse messages generated locally
to compute the hash. Or the parse a log/event from the settlement
chain in order to build the L1HandlerTransaction.
Copy link
Member

@kariy kariy left a comment

Choose a reason for hiding this comment

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

looking good so far...

the starknet-messaging is very opinionated but should be a good experiment to play around with katana <-> katana messaging. it is hidden under a feature and isn't enable by default.

we can keep the scripts and the foundry project to help setting up the messaging system quickly.

@kariy kariy force-pushed the messaging-rework branch from 03ff224 to 1a14b8d Compare October 2, 2023 17:38
@kariy
Copy link
Member

kariy commented Oct 2, 2023

lgtm

happy to merge this if there's no more necessary updates

@glihm
Copy link
Collaborator Author

glihm commented Oct 2, 2023

lgtm

happy to merge this if there's no more necessary updates

On my side it's all good.
Newly, thanks a lot @kariy for your time and feedback on this work. 🙏

@kariy kariy merged commit becd902 into dojoengine:main Oct 2, 2023
9 checks passed
@glihm glihm deleted the messaging-rework branch December 20, 2023 16:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants