diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf.rs b/zkevm-circuits/src/mpt_circuit/account_leaf.rs index 95063dfeb2..4b518911b5 100644 --- a/zkevm-circuits/src/mpt_circuit/account_leaf.rs +++ b/zkevm-circuits/src/mpt_circuit/account_leaf.rs @@ -205,6 +205,8 @@ impl AccountLeafConfig { MPTProofType::CodeHashChanged.expr(), ); + let is_wrong_ext_case = parent_data[1].is_last_level_and_wrong_ext_case.expr(); + for is_s in [true, false] { ifx! {not!(config.is_mod_extension[is_s.idx()].expr()) => { // Placeholder leaf checks @@ -273,7 +275,9 @@ impl AccountLeafConfig { // Total number of nibbles needs to be KEY_LEN_IN_NIBBLES. let num_nibbles = num_nibbles::expr(rlp_key.key_value.len(), key_data[is_s.idx()].is_odd.expr()); - require!(key_data[is_s.idx()].num_nibbles.expr() + num_nibbles.expr() => KEY_LEN_IN_NIBBLES); + ifx! {not!(is_wrong_ext_case) => { + require!(key_data[is_s.idx()].num_nibbles.expr() + num_nibbles.expr() => KEY_LEN_IN_NIBBLES); + }} // Check if the leaf is in its parent. // Check is skipped for placeholder leaves which are dummy leaves. @@ -282,7 +286,8 @@ impl AccountLeafConfig { // Note that the constraint works for the case when there is the placeholder branch above // the leaf too - in this case `parent_data.hash` contains the hash of the node above the placeholder // branch. - ifx! {not!(config.is_placeholder_leaf[is_s.idx()]) => { + ifx! {not!(or::expr(&[config.is_placeholder_leaf[is_s.idx()].expr(), is_wrong_ext_case.clone()])) => { + // ifx! {not!(config.is_placeholder_leaf[is_s.idx()]) => { let hash = parent_data[is_s.idx()].hash.expr(); require!((1.expr(), leaf_rlc, rlp_key.rlp_list.num_bytes(), hash.lo(), hash.hi()) =>> @KECCAK); } elsex { @@ -305,7 +310,9 @@ impl AccountLeafConfig { // Note that this does not hold when there is NonExistingAccountProof wrong leaf scenario, // in this case there is a non-nil leaf. However, in this case the leaf is not a placeholder, // so the check below is not triggered. - require!(parent_data[is_s.idx()].rlc.expr() => 128.expr()); + ifx! {not!(is_wrong_ext_case) => { + require!(parent_data[is_s.idx()].rlc.expr() => 128.expr()); + }} }} }} }} @@ -407,18 +414,20 @@ impl AccountLeafConfig { // To check whether it's wrong extension node - is_last_level_and_wrong_ext_case = 1, parent is extension // To check whether it's the nil leaf - use IsPlaceholderLeafGadget + // TODO: when is_last_level_and_wrong_ext_case, the proof type needs to be non-existing + // config.is_non_existing_account_proof.expr(), + // config.parent_data[true.idx()].is_extension.expr(), + config.wrong_ext_node = WrongExtNodeGadget::construct( cb, key_item.hash_rlc(), - config.is_non_existing_account_proof.expr(), + is_wrong_ext_case, &wrong_ext_middle, &wrong_ext_middle_nibbles, &wrong_ext_after, &wrong_ext_after_nibbles, - config.parent_data[true.idx()].is_extension.expr(), config.key_data[true.idx()].clone(), config.key_data_prev.clone(), - &cb.key_r.expr(), ); // Anything following this node is below the account diff --git a/zkevm-circuits/src/mpt_circuit/branch.rs b/zkevm-circuits/src/mpt_circuit/branch.rs index 56ba3e8312..8f36d7eb4a 100644 --- a/zkevm-circuits/src/mpt_circuit/branch.rs +++ b/zkevm-circuits/src/mpt_circuit/branch.rs @@ -64,6 +64,7 @@ impl BranchGadget { key_mult: Expression, num_nibbles: Expression, is_key_odd: Expression, + is_last_level_and_wrong_ext_case: Expression, ) -> Self { let mut config = BranchGadget::default(); @@ -193,7 +194,7 @@ impl BranchGadget { ) }; - ifx! {not!(is_placeholder[is_s.idx()]) => { + ifx! {not!(or::expr(&[is_placeholder[is_s.idx()].expr(), is_last_level_and_wrong_ext_case.clone()])) => { ifx!{or::expr(&[is_root[is_s.idx()].expr(), not!(is_not_hashed)]) => { // Hashed branch hash in parent branch let hash = &parent_hash[is_s.idx()]; diff --git a/zkevm-circuits/src/mpt_circuit/extension_branch.rs b/zkevm-circuits/src/mpt_circuit/extension_branch.rs index 28b1f99ae8..174d0cfe80 100644 --- a/zkevm-circuits/src/mpt_circuit/extension_branch.rs +++ b/zkevm-circuits/src/mpt_circuit/extension_branch.rs @@ -135,6 +135,7 @@ impl ExtensionBranchConfig { key_mult_post_ext.expr(), num_nibbles.expr(), is_key_odd.expr(), + config.is_last_level_and_wrong_ext_case.expr(), ); let branch = config.branch.get_post_state(); diff --git a/zkevm-circuits/src/mpt_circuit/helpers.rs b/zkevm-circuits/src/mpt_circuit/helpers.rs index b514106e92..d8abcae403 100644 --- a/zkevm-circuits/src/mpt_circuit/helpers.rs +++ b/zkevm-circuits/src/mpt_circuit/helpers.rs @@ -1329,20 +1329,17 @@ impl WrongExtNodeGadget { pub(crate) fn construct( cb: &mut MPTConstraintBuilder, expected_key: Expression, - is_non_existing: Expression, + is_wrong_ext_case: Expression, wrong_ext_middle: &RLPItemView, wrong_ext_middle_nibbles: &RLPItemView, wrong_ext_after: &RLPItemView, wrong_ext_after_nibbles: &RLPItemView, - is_parent_extension: Expression, key_data: KeyData, key_data_prev: KeyData, - r: &Expression, ) -> Self { let mut config = WrongExtNodeGadget::default(); circuit!([meta, cb.base], { - // TODO: distinguish between wrong extension node / wrong leaf / nil leaf - ifx! {and::expr(&[is_non_existing, is_parent_extension]) => { + ifx! {is_wrong_ext_case => { // We have a key split into three parts, // meaning that there the first part parity doesn't // tell us about the parity of the second part (depends on the third part as well).