Skip to content
This repository has been archived by the owner on Dec 15, 2023. It is now read-only.

Commit

Permalink
L1 l2 improvements (#41)
Browse files Browse the repository at this point in the history
* Changed flush output, clearing l2_message array

* Improved flush usage, refactor postman tests

* Fixed according to PR review
  • Loading branch information
dribeiro-ShardLabs committed Feb 25, 2022
1 parent 5b122da commit 4ac579b
Show file tree
Hide file tree
Showing 17 changed files with 572 additions and 1,018 deletions.
920 changes: 464 additions & 456 deletions poetry.lock

Large diffs are not rendered by default.

6 changes: 2 additions & 4 deletions scripts/setup_example.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ cd starknet-hardhat-example
npm ci
npm link @shardlabs/starknet-hardhat-plugin

echo "Installing ganache-cli and truffle"
npm install -g ganache-cli
npm install -g truffle

# generate artifacts
npx hardhat starknet-compile

npx hardhat compile
6 changes: 4 additions & 2 deletions starknet_devnet/postman_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def __init__(self):
self.web3: Web3 = None
self.mock_starknet_messaging_contract: EthContract = None
self.eth_account: EthAccount = None
self.l1_to_l2_message_filter = None

@abstractmethod
def load_mock_messaging_contract_in_l1(self, starknet, contract_address):
Expand All @@ -29,8 +30,8 @@ async def flush(self):
"""Handles the L1 <> L2 message exchange"""
await self.postman.flush()

class GanachePostmanWrapper(PostmanWrapper):
"""Wrapper of Postman usage on a local testnet instantiated using Ganache"""
class LocalPostmanWrapper(PostmanWrapper):
"""Wrapper of Postman usage on a local testnet instantiated using a local testnet"""

def __init__(self, network_url: str):
super().__init__()
Expand All @@ -49,3 +50,4 @@ def load_mock_messaging_contract_in_l1(self, starknet, contract_address):
self.mock_starknet_messaging_contract = EthContract(self.web3,address,w3_contract,abi,self.eth_account)

self.postman = Postman(self.mock_starknet_messaging_contract,starknet)
self.l1_to_l2_message_filter = self.mock_starknet_messaging_contract.w3_contract.events.LogMessageToL2.createFilter(fromBlock="latest")
5 changes: 1 addition & 4 deletions starknet_devnet/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ async def add_transaction():
abort(Response(f"Invalid tx_type: {tx_type}.", 400))

# after tx
await starknet_wrapper.postman_flush()
if dumper.dump_on == DumpOn.TRANSACTION:
dumper.dump()

Expand Down Expand Up @@ -87,8 +86,6 @@ async def call_contract():
# code 400 would make more sense, but alpha returns 500
abort(Response(err.message, 500))

await starknet_wrapper.postman_flush()

return jsonify(result_dict)

def validate_call(data: bytes):
Expand Down Expand Up @@ -198,7 +195,7 @@ async def load_l1_messaging_contract():
"""
Loads a MockStarknetMessaging contract. If one is already deployed in the L1 network specified by the networkUrl argument,
in the address specified in the address argument in the POST body, it is used, otherwise a new one will be deployed.
The networkId argument is used to check if a local Ganache instance or a testnet should be used.
The networkId argument is used to check if a local testnet instance or a public testnet should be used.
"""

request_dict = json.loads(request.data.decode("utf-8"))
Expand Down
48 changes: 38 additions & 10 deletions starknet_devnet/starknet_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
starkware.starknet.testing.starknet.Starknet.
"""

import json
import time
from copy import deepcopy
from typing import Dict
from web3 import Web3

import dill as pickle
from starkware.starknet.business_logic.internal_transaction import InternalInvokeFunction
Expand All @@ -22,7 +24,7 @@
from .util import Choice, StarknetDevnetException, TxStatus, fixed_length_hex, DummyExecutionInfo, enable_pickling
from .contract_wrapper import ContractWrapper
from .transaction_wrapper import TransactionWrapper, DeployTransactionWrapper, InvokeTransactionWrapper
from .postman_wrapper import GanachePostmanWrapper
from .postman_wrapper import LocalPostmanWrapper
from .constants import FAILURE_REASON_KEY

enable_pickling()
Expand Down Expand Up @@ -392,20 +394,21 @@ async def get_storage_at(self, contract_address: int, key: int) -> str:
async def load_messaging_contract_in_l1(self, network_url: str, contract_address: str, network_id: str) -> dict:
"""Creates a Postman Wrapper instance and loads an already deployed Messaging contract in the L1 network"""

# If no L1 network ID provided, will use a Ganache instance
if network_id is None or network_id == "ganache":
# If no L1 network ID provided, will use a local testnet instance
if network_id is None or network_id == "local":
try:
starknet = await self.get_starknet()
self.__postman_wrapper = GanachePostmanWrapper(network_url)
starknet.state.l2_to_l1_messages_log.clear()
self.__postman_wrapper = LocalPostmanWrapper(network_url)
self.__postman_wrapper.load_mock_messaging_contract_in_l1(starknet,contract_address)
except Exception as error:
message = f"""Exception when trying to load the Starknet Messaging contract in a Ganache instance.
Make sure you have a Ganache instance running at the provided network url, and that the Messaging Contract is deployed at the provided address
message = f"""Exception when trying to load the Starknet Messaging contract in a local testnet instance.
Make sure you have a local testnet instance running at the provided network url, and that the Messaging Contract is deployed at the provided address
Exception:
{error}"""
raise StarknetDevnetException(message=message) from error
else:
message = "L1 interaction is only usable with a local running Ganache instance."
message = "L1 interaction is only usable with a local running local testnet instance."
raise StarknetDevnetException(message=message)

self.__l1_provider = network_url
Expand All @@ -418,14 +421,39 @@ async def postman_flush(self) -> dict:
"""Handles all pending L1 <> L2 messages and sends them to the other layer. """

state = await self.__get_state()
l2_to_l1_messages = state.l2_to_l1_messages_log

if self.__postman_wrapper is None:
return {}

postman = self.__postman_wrapper.postman

l1_to_l2_messages = json.loads(Web3.toJSON(self.__postman_wrapper.l1_to_l2_message_filter.get_new_entries()))
l2_to_l1_messages = state.l2_to_l1_messages_log[postman.n_consumed_l2_to_l1_messages :]

await self.__postman_wrapper.flush()

return self.parse_l1_l2_messages(l1_to_l2_messages, l2_to_l1_messages)

def parse_l1_l2_messages(self, l1_raw_messages, l2_raw_messages) -> dict:
"""Converts some of the values in the dictionaries from integer to hex"""

for message in l1_raw_messages:
message["args"]["selector"] = hex(message["args"]["to_address"])
message["args"]["to_address"] = hex(message["args"]["to_address"])

l2_messages = []
for message in l2_raw_messages:
new_message = {
"from_address": hex(message.from_address),
"payload": message.payload,
"to_address": hex(message.to_address)
}
l2_messages.append(new_message)

return {
"l1_provider": self.__l1_provider,
"n_consumed_l2_to_l1_messages": self.__postman_wrapper.postman.n_consumed_l2_to_l1_messages,
"consumed_l2_messages": l2_to_l1_messages
"consumed_messages": {
"from_l1": l1_raw_messages,
"from_l2": l2_messages
}
}
54 changes: 0 additions & 54 deletions test/contracts/IStarknetMessaging.sol

This file was deleted.

67 changes: 0 additions & 67 deletions test/contracts/L1L2Example.sol

This file was deleted.

23 changes: 0 additions & 23 deletions test/contracts/Migrations.sol

This file was deleted.

38 changes: 0 additions & 38 deletions test/contracts/MockStarknetMessaging.sol

This file was deleted.

Loading

0 comments on commit 4ac579b

Please sign in to comment.