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

Adding support for declare v0, l1 handler and l1->l2 messages #321

Merged
merged 35 commits into from
Oct 21, 2024

Conversation

Mohiiit
Copy link
Contributor

@Mohiiit Mohiiit commented Oct 10, 2024

Support has been added for declare v0 transaction, this would be required in order to declare txn with zero fees.
Support for l1 handler txn is also added
l1->l2 feature was implemented was not in use, added that as well.

Pull Request type

Please add the labels corresponding to the type of changes your PR introduces:

  • Feature

What is the current behavior?

  1. the code don't have support for declare v0
  2. currently the l1 handler txn are ignore
  3. it's not added in the l1 sync service

Resolves: #NA

What is the new behavior?

  • declare v0 support has been added
  • supports l1 handler txn
  • should be able to execute l1->l2 messages

Does this introduce a breaking change?

Shouldn't

Other information

@Mohiiit Mohiiit marked this pull request as ready for review October 10, 2024 16:04
let mut event_stream = event_filter
.from_block(last_synced_event_block.block_number)
.select(BlockNumberOrTag::Finalized)
Copy link
Contributor

Choose a reason for hiding this comment

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

we should add this back?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it was causing the issue actually, was not able to get the messages

Copy link
Contributor

Choose a reason for hiding this comment

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

maybe it's an issue because anvil creates blocks only when a txn comes. so your block isn't finalised until you create more blocks on top (I guess). however, if we read a message which isn't finalised (and so it rolls back on Ethereum which is very rare) there can be big downstream issues

crates/client/mempool/src/block_production.rs Outdated Show resolved Hide resolved

if let Transaction::AccountTransaction(account_tx) = clone_transaction(&tx) {
let _ = validator.perform_validations(account_tx, deploy_account_tx_hash.is_some());
}

if !is_only_query(&tx) {
Copy link
Contributor

Choose a reason for hiding this comment

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

probably not for this PR but shouldn't we throw an error if someone calls add_invoke_transaction as a query? query versions should only be allowed in estimate_fee and estimate_message_fee imo. so if it's a query version on a write call we can revert much earlier maybe?

Copy link
Member

Choose a reason for hiding this comment

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

good question, i'm not entirely sure?

events,
execution_resources,
execution_result,
message_hash: Felt::from(1),
Copy link
Contributor

Choose a reason for hiding this comment

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

add a TODO?

Copy link
Member

Choose a reason for hiding this comment

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

i dont remember how the message hash is computed, i think the stuff that's commented just on top may work?
we should make a unit test for that tbh

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it's implemented now

crates/primitives/receipt/src/from_blockifier.rs Outdated Show resolved Hide resolved

// TODO: remove unwraps
// Ques: shall it panic if no block number of event_index?
Copy link
Collaborator

Choose a reason for hiding this comment

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

I have checked and could not find any check for None on any of these fields from the moment they are created to this point. This is quite worrying. I do not know what the expected behavior would be in that case but this should not cause a node failure.

crates/client/mempool/src/block_production.rs Outdated Show resolved Hide resolved
crates/primitives/class/src/lib.rs Outdated Show resolved Hide resolved
crates/primitives/class/src/lib.rs Outdated Show resolved Hide resolved
crates/primitives/class/src/lib.rs Outdated Show resolved Hide resolved
crates/primitives/class/src/lib.rs Outdated Show resolved Hide resolved
crates/primitives/receipt/src/from_blockifier.rs Outdated Show resolved Hide resolved
Copy link
Member

@cchudant cchudant left a comment

Choose a reason for hiding this comment

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

good!

  • mempool handling: l1 handler tx nonces is not handled properly, but I will probably fix that myself
  • rpc endpoint declare v0 should not be public, declare v0 is only for bootstrapper. Ideally in a dedicated node operator endpoint.
  • l1 to l2 messages - good, i'd love a test of some kind though
    • message hash is wrong

crates/client/mempool/src/block_production.rs Outdated Show resolved Hide resolved
crates/client/mempool/src/inner.rs Outdated Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

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

there is a

#![proptest_config(ProptestConfig::with_cases(5))] // comment this when developing, this is mostly for faster ci & whole workspace `cargo test`

at the bottom of the file that you should try commenting to see if the proptest passes locally
(don't commit it though)

Copy link
Member

Choose a reason for hiding this comment

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

This is fine for now, but please add a comment saying that the handling of nonces on l1 handler txs is wrong

Also, when I get to fixing it, what tests should I run to see that I did not break l1 messages in the process?

.gitignore Show resolved Hide resolved
@@ -63,11 +63,13 @@ impl Error {
#[cfg_attr(test, mockall::automock)]
pub trait MempoolProvider: Send + Sync {
fn accept_invoke_tx(&self, tx: BroadcastedInvokeTransaction) -> Result<InvokeTransactionResult, Error>;
fn accept_declare_v0_tx(&self, tx: BroadcastedDeclareTransactionV0) -> Result<DeclareTransactionResult, Error>;
Copy link
Member

Choose a reason for hiding this comment

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

might be worth to put a comment here to say why we need declare v0 txs in the first place

crates/primitives/class/src/lib.rs Outdated Show resolved Hide resolved
events,
execution_resources,
execution_result,
message_hash: Felt::from(1),
Copy link
Member

Choose a reason for hiding this comment

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

i dont remember how the message hash is computed, i think the stuff that's commented just on top may work?
we should make a unit test for that tbh

crates/client/eth/src/l1_messaging.rs Outdated Show resolved Hide resolved
crates/tests/src/lib.rs Outdated Show resolved Hide resolved
crates/primitives/chain_config/src/chain_config.rs Outdated Show resolved Hide resolved
crates/tests/src/lib.rs Outdated Show resolved Hide resolved
crates/node/src/service/rpc/middleware.rs Show resolved Hide resolved
crates/proc-macros/src/lib.rs Show resolved Hide resolved
crates/client/mempool/src/inner.rs Show resolved Hide resolved
Trantorian1
Trantorian1 previously approved these changes Oct 17, 2024
crates/client/mempool/src/inner.rs Outdated Show resolved Hide resolved
@Trantorian1 Trantorian1 dismissed their stale review October 17, 2024 07:39

Missclick :P

crates/proc-macros/src/lib.rs Show resolved Hide resolved
crates/node/src/service/rpc/middleware.rs Outdated Show resolved Hide resolved
) -> anyhow::Result<()> {
// This is a provisory check to avoid updating the state with an L1StateUpdate that should not have been detected
//
// TODO: Remove this check when the L1StateUpdate is properly verified
if state_update.block_number > 500000u64 || chain_id == MAIN_CHAIN_ID {
if state_update.block_number > 500000u64 || chain_id.to_felt() == MAIN_CHAIN_ID {
Copy link
Member

Choose a reason for hiding this comment

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

I don't really understand this logic and the 'or'

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 believe the logic was in place before this and if I remember correctly it was because there was some mismatch before specific on mainnet

@@ -46,8 +46,8 @@ impl RpcService {
(true, false)
}
};
let (read, write, trace) = (rpcs, rpcs, rpcs);
let starknet = Starknet::new(Arc::clone(db.backend()), chain_config.clone(), add_txs_method_provider);
let (read, write, trace, internal) = (rpcs, rpcs, rpcs, node_operator);
Copy link
Member

Choose a reason for hiding this comment

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

It will eventually be necessary to secure the origin of internal calls (verification of origin, bind on a specific port, etc.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ideally internal call shouldn't be public, so yeah I agree, shall we cover this in this PR tho?

Transaction::L1HandlerTransaction(tx) => match get_l1_handler_message_hash(tx) {
Ok(hash) => Some(hash),
Err(err) => {
panic!("Error getting l1 handler message hash: {:?}", err);
Copy link
Member

Choose a reason for hiding this comment

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

the error should be reported

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed it to log the error

TransactionHash(hash),
class_info,
None,
deployed_address.map(|address| address.try_into().unwrap()),
Copy link
Member

Choose a reason for hiding this comment

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

uses expect to explain that this should not panic

Copy link
Contributor Author

Choose a reason for hiding this comment

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

actually we don't need it for declare v0 but it was missing in other case so added there

) -> Self {
let is_query = tx.is_query;
let transaction: Transaction =
Transaction::Declare(DeclareTransaction::from_broadcasted_declare_v0(tx, class_hash.unwrap()));
Copy link
Member

Choose a reason for hiding this comment

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

same

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@@ -40,6 +46,26 @@ impl TransactionWithHash {
}
}

#[derive(Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
Copy link
Member

Choose a reason for hiding this comment

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

maybe de/serialization tests

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added

@jbcaron
Copy link
Member

jbcaron commented Oct 21, 2024

there is an issue to start madara in sequencer without L1 synchronization:
L1 gas prices require the ethereum service to be enabled. Either disable gas prices syncing using --gas-price 0, or disable L1 sync using the --no-l1-sync argument.

@Mohiiit
Copy link
Contributor Author

Mohiiit commented Oct 21, 2024

there is an issue to start madara in sequencer without L1 synchronization:
L1 gas prices require the ethereum service to be enabled. Either disable gas prices syncing using --gas-price 0, or disable L1 sync using the --no-l1-sync argument.

This makes sense right? if the user wants to set a price and don't want a l1-sync they can just pass --no-l1-sync

Copy link
Member

@cchudant cchudant left a comment

Choose a reason for hiding this comment

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

cool!

let mempool_tx_hash = mempool_tx.tx_hash();

let replaced = if force {
if self.transactions.insert(OrderMempoolTransactionByNonce(mempool_tx), ()).is_some() {
if self.transactions.insert(OrderMempoolTransactionByNonce(mempool_tx.clone()), ()).is_some() {
Copy link
Member

Choose a reason for hiding this comment

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

why clone?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed

ReplacedState::Replaced
} else {
ReplacedState::NotReplaced
}
} else {
match self.transactions.entry(OrderMempoolTransactionByNonce(mempool_tx)) {
match self.transactions.entry(OrderMempoolTransactionByNonce(mempool_tx.clone())) {
Copy link
Member

Choose a reason for hiding this comment

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

same

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed

@antiyro antiyro merged commit de11ced into main Oct 21, 2024
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

6 participants