Skip to content

core/vm: add kzg precompile back for madhugiri forks#2140

Merged
manav2401 merged 7 commits intov2.7.0-candidatefrom
manav/enable-kzg-back
Mar 19, 2026
Merged

core/vm: add kzg precompile back for madhugiri forks#2140
manav2401 merged 7 commits intov2.7.0-candidatefrom
manav/enable-kzg-back

Conversation

@manav2401
Copy link
Member

Description

Add KZG precompile back for Madhugiri / MadhugiriPro.

It was removed while enabling LisovoPro HF from all previous precompiles while those blocks already used the precompile. This PR adds it back so that nodes don't return bad block errors while syncing past blocks (between Madhugiri/MadhugiriPro and Lisovo/LisovoPro).

Changes

  • Bugfix (non-breaking change that solves an issue)
  • Hotfix (change that solves an urgent issue, and requires immediate attention)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (change that is not backwards-compatible and/or changes current functionality)
  • Changes only for a subset of nodes

Breaking changes

Please complete this section if any breaking changes have been made, otherwise delete it

Nodes audience

In case this PR includes changes that must be applied only to a subset of nodes, please specify how you handled it (e.g. by adding a flag with a default value...)

Checklist

  • I have added at least 2 reviewer or the whole pos-v1 team
  • I have added sufficient documentation in code
  • I will be resolving comments - if any - by pushing each fix in a separate commit and linking the commit hash in the comment reply
  • Created a task in Jira and informed the team for implementation in Erigon client (if applicable)
  • Includes RPC methods changes, and the Notion documentation has been updated

Cross repository changes

  • This PR requires changes to heimdall
    • In case link the PR here:
  • This PR requires changes to matic-cli
    • In case link the PR here:

Testing

  • I have added unit tests
  • I have added tests to CI
  • I have tested this code manually on local environment
  • I have tested this code manually on remote devnet using express-cli
  • I have tested this code manually on amoy
  • I have created new e2e tests into express-cli

Manual tests

Please complete this section with the steps you performed if you ran manual tests for this functionality, otherwise delete it

Additional comments

Please post additional comments in this section if you have them, otherwise delete it

@claude
Copy link

claude bot commented Mar 13, 2026

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

@codecov
Copy link

codecov bot commented Mar 13, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (v2.7.0-candidate@2b949e9). Learn more about missing BASE report.

Additional details and impacted files

Impacted file tree graph

@@                 Coverage Diff                 @@
##             v2.7.0-candidate    #2140   +/-   ##
===================================================
  Coverage                    ?   51.58%           
===================================================
  Files                       ?      882           
  Lines                       ?   154208           
  Branches                    ?        0           
===================================================
  Hits                        ?    79552           
  Misses                      ?    69482           
  Partials                    ?     5174           
Files with missing lines Coverage Δ
core/vm/contracts.go 76.15% <ø> (ø)
Files with missing lines Coverage Δ
core/vm/contracts.go 76.15% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@adamdossa
Copy link
Contributor

@claude review

@claude
Copy link

claude bot commented Mar 13, 2026

Claude finished @adamdossa's task in 1m 3s —— View job


Review of PR #2140

  • Read changed file and surrounding context
  • Review for correctness and security
  • Post review findings

Verdict: Looks good. This is a correct and necessary bugfix.

Analysis

The PR adds &kzgPointEvaluation{} at address 0x0a to three precompile maps:

  • PrecompiledContractsPrague (contracts.go:137)
  • PrecompiledContractsMadhugiri (contracts.go:194)
  • PrecompiledContractsMadhugiriPro (contracts.go:216)

Why this is correct: Both Madhugiri and MadhugiriPro forks were deployed with the KZG precompile active (inherited from the Cancun/Prague lineage). Removing it from these maps would cause nodes to reject historical blocks that called the 0x0a precompile during those fork periods, producing "bad block" errors during sync. This fix restores the precompile so historical block verification succeeds.

Consistency check across all fork precompile maps:

Fork Has kzgPointEvaluation?
Homestead → Berlin No (pre-Cancun, correct)
Cancun No (uses p256Verify at 0x100 instead)
Prague Yes ✅ (added in this PR)
Osaka Yes ✅
Madhugiri Yes ✅ (added in this PR)
MadhugiriPro Yes ✅ (added in this PR)
Lisovo Yes ✅
LisovoPro No

Question

PrecompiledContractsLisovoPro (line 252-270) is the only post-Madhugiri fork map that doesn't include kzgPointEvaluation. Lisovo (its predecessor) has it, and the later forks would typically inherit it. Is this intentional, or should LisovoPro also have the KZG precompile? If it's intentional (e.g., KZG was deliberately removed at this fork boundary), it might be worth adding a brief comment explaining why.

No other issues found — the change is minimal, correct, and addresses a real sync-breaking bug.


common.BytesToAddress([]byte{0x07}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{0x08}): &bn256PairingIstanbul{},
common.BytesToAddress([]byte{0x09}): &blake2F{},
common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{},
Copy link

Choose a reason for hiding this comment

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

🔴 PrecompiledContractsLisovoPro (line 252) is also missing the KZG precompile at 0x0a — it jumps from 0x09 (blake2F) directly to 0x0b (bls12381G1Add). Since activePrecompiledContracts checks IsLisovoPro first, nodes running the latest fork will lack the KZG point evaluation precompile, which is consensus-affecting. The same common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{} entry added to the other maps needs to be added here too.

Extended reasoning...

What the bug is

This PR restores the KZG point evaluation precompile (kzgPointEvaluation at address 0x0a) to PrecompiledContractsPrague, PrecompiledContractsMadhugiri, and PrecompiledContractsMadhugiriPro. However, PrecompiledContractsLisovoPro — which suffers from the exact same omission — is not fixed. Looking at lines 252–270, the map jumps from 0x09 (blake2F) directly to 0x0b (bls12381G1Add) with no 0x0a entry.

Why this matters

The activePrecompiledContracts function (line 327) uses a switch statement where rules.IsLisovoPro is the first case checked. This means for nodes running the latest fork rules, PrecompiledContractsLisovoPro is the active precompile set. Any call to address 0x0a (the KZG point evaluation precompile) will fail because the address is not registered in that map.

Proof by example

  1. A contract on the LisovoPro fork calls address 0x0a to perform a KZG point evaluation.
  2. The EVM calls activePrecompiledContracts(rules), which returns PrecompiledContractsLisovoPro (line 328).
  3. The precompile lookup for address 0x0a finds no entry in the map.
  4. The call is treated as a call to a regular (empty) account, not as a precompile — returning unexpected results.
  5. Meanwhile, the predecessor fork PrecompiledContractsLisovo (line 229) does include 0x0a: &kzgPointEvaluation{}, so this is a regression from Lisovo to LisovoPro.

Impact

This is a consensus-affecting bug. Nodes running LisovoPro will disagree with nodes that expect KZG to be available (as it was in every fork from Cancun/Prague onward). The PR description itself states the KZG precompile "was removed while enabling LisovoPro HF," yet the fix does not restore it to the LisovoPro precompile set.

Fix

Add the missing line to PrecompiledContractsLisovoPro:

common.BytesToAddress([]byte{0x0a}):       &kzgPointEvaluation{},

between the 0x09 (blake2F) and 0x0b (bls12381G1Add) entries, matching what was done for Prague, Madhugiri, and MadhugiriPro in this same PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is not true. When an EVM instance is created (in NewEVM function in core/vm/evm.go file), it activates precompiles based on current block number. So, if bor is executing an old block, it would activate a precompile activated at that block (and not the latest). This means old blocks in Madhugiri (and other forks) will still have kzg precompile enabled but blocks after LisovoPro won't have it enabled. Moreover, LisovoPro HF removes kzg precompile fully so it's intentional.

Copilot AI review requested due to automatic review settings March 19, 2026 10:29
@manav2401 manav2401 changed the base branch from develop to v2.7.0-candidate March 19, 2026 10:29
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Re-enables the EIP-4844 KZG point-evaluation precompile (0x0a) for older Bor hardfork eras to prevent “bad block” errors when syncing historical blocks across Madhugiri/MadhugiriPro → Lisovo/LisovoPro transitions.

Changes:

  • Add kzgPointEvaluation (0x0a) to PrecompiledContractsMadhugiri
  • Add kzgPointEvaluation (0x0a) to PrecompiledContractsMadhugiriPro
  • Add kzgPointEvaluation (0x0a) to PrecompiledContractsPrague

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines 134 to 138
common.BytesToAddress([]byte{0x07}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{0x08}): &bn256PairingIstanbul{},
common.BytesToAddress([]byte{0x09}): &blake2F{},
common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{},
common.BytesToAddress([]byte{0x0b}): &bls12381G1Add{},
Comment on lines 192 to 196
common.BytesToAddress([]byte{0x08}): &bn256PairingIstanbul{},
common.BytesToAddress([]byte{0x09}): &blake2F{},
common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{},
common.BytesToAddress([]byte{0x0b}): &bls12381G1Add{},
common.BytesToAddress([]byte{0x0c}): &bls12381G1MultiExp{},
Copilot AI review requested due to automatic review settings March 19, 2026 11:23
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Reintroduces the KZG point evaluation precompile (0x0a) for the Bor-specific Madhugiri/MadhugiriPro hardfork precompile sets to prevent “bad block” errors when syncing historical ranges where those forks expected the precompile to exist.

Changes:

  • Add kzgPointEvaluation (0x0a) back into PrecompiledContractsMadhugiri and PrecompiledContractsMadhugiriPro.
  • Update the existing test to assert KZG precompile presence/absence across multiple fork rule configurations.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
core/vm/contracts.go Re-adds KZG (0x0a) to Madhugiri/MadhugiriPro precompile maps (and adds a note in Osaka’s map).
core/vm/contracts_test.go Refactors the KZG precompile test into a table-driven check across forks.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 19, 2026 12:21
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR restores the KZG point-evaluation precompile (0x0a) for the Bor-specific Madhugiri and MadhugiriPro forks to avoid “bad block” errors when syncing historical blocks across the Madhugiri↔Lisovo fork range.

Changes:

  • Re-enabled the kzgPointEvaluation precompile at address 0x0a in PrecompiledContractsMadhugiri and PrecompiledContractsMadhugiriPro.
  • Updated the unit test to validate KZG precompile presence across multiple forks (pre-Madhugiri, Madhugiri/MadhugiriPro/Lisovo, and removal at LisovoPro).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
core/vm/contracts.go Adds 0x0a -> kzgPointEvaluation to Madhugiri and MadhugiriPro precompile sets.
core/vm/contracts_test.go Adjusts the KZG precompile test to cover multiple hardfork rule configurations.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@manav2401 manav2401 merged commit 21922c7 into v2.7.0-candidate Mar 19, 2026
5 of 7 checks passed
@manav2401 manav2401 deleted the manav/enable-kzg-back branch March 19, 2026 12:30
@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
9.7% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

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.

5 participants