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

Fix Genesis block hash calculation for Testnet network #566

Merged
merged 3 commits into from
Oct 2, 2024

Conversation

m-Peter
Copy link
Collaborator

@m-Peter m-Peter commented Sep 23, 2024

Closes: #534

Description

  1. The hash calculation for the Genesis block on Testnet should be done without the PrevRandao field, as it was introduced later, and it produces a different hash.

  2. The ParentHash for the first EVM block that contains the PrevRandao field, is pointing to a non-existent block. Relevant events:

A.8c5303eaa26202d6.EVM.BlockExecuted(
    height: 1385490,
    hash: "0xfc9a0204b12bc4875ed880300d07f27de4f9857be67d13cf72f53b09e8942ced",
    timestamp: 1724362036,
    totalSupply: 37735203666010000000000,
    totalGasUsed: 0,
    parentHash: "0x95b9d3a30ce797062ab5162d6dc4c60d887ff66eeec49640931c2d7ac014974d",
    receiptRoot: [86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33],
    transactionHashRoot: [86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33]
)

A.8c5303eaa26202d6.EVM.BlockExecuted(
    height: 1385491,
    hash: "0x829f0aeea56301ca085a9688f0ab238f2738e553a09e00963170d92c08957daa",
    timestamp: 1724362037,
    totalSupply: 37735203666010000000000,
    totalGasUsed: 0,
    parentHash: "0x0e742970c53cc2924d55830a588609ca1db460cce41850df7af119639fe42d91",
    receiptRoot: [86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33],
    transactionHashRoot: [86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33],
    prevrandao: [84, 243, 47, 99, 190, 212, 43, 169, 197, 65, 166, 231, 112, 226, 218, 121, 153, 240, 149, 165, 22, 98, 37, 215, 150, 128, 215, 244, 192, 84, 175, 161]
)

Note: After deployment, a re-index is needed for this code to take effect.


For contributor use:

  • Targeted PR against master branch
  • Linked to Github issue with discussion and accepted design OR link to spec that describes this work.
  • Code follows the standards mentioned here.
  • Updated relevant documentation
  • Re-reviewed Files changed in the Github PR explorer
  • Added appropriate labels

Summary by CodeRabbit

  • New Features

    • Introduced specific logic for creating a Genesis block for the Testnet chain, ensuring it meets the unique requirements of this environment.
    • Enhanced block retrieval logic to handle specific block heights and update parent block hashes for Testnet.
  • Tests

    • Added a new test to verify the hash of the Genesis block for Testnet, ensuring accuracy and reliability of the implementation.

@m-Peter m-Peter added this to the Flow-EVM-M2 milestone Sep 23, 2024
@m-Peter m-Peter self-assigned this Sep 23, 2024
Copy link
Contributor

coderabbitai bot commented Sep 23, 2024

Walkthrough

The changes implement a mechanism for handling the Genesis block specifically for the flow.Testnet chain. A new variable and mapping are introduced to manage event IDs and block hash calculations. The GenesisBlock function is modified to create a blockV0 structure without the PrevRandao field, and its hash is computed accordingly. Additionally, a new test function is added to validate the hash of the Genesis block for Testnet. The logic for handling specific block heights with broken parent hashes is also expanded.

Changes

Files Change Summary
models/block.go Introduced logic for Testnet block handling, including a new variable for event ID and a mapping for block hashes. Modified GenesisBlock to create a blockV0 structure without PrevRandao. Updated decodeBlockEvent to conditionally set ParentBlockHash.
models/block_test.go Added Test_GenesisBlockHashForTestnet to verify the hash of the Genesis block for Testnet.
storage/pebble/blocks.go Added logic in getBlock to handle specific block heights for Testnet, updating ParentBlockHash accordingly. Introduced a new variable for broken parent hash heights.

Assessment against linked issues

Objective Addressed Explanation
Inconsistencies in parent hashes for blocks (534)
Ensure correct hash computation for Genesis block (534)

Possibly related PRs

Suggested reviewers

  • peterargue

Poem

🐇 In the code where the blocks do play,
A new path for Testnet found its way.
With hashes computed, all in a row,
The Genesis shines with a radiant glow.
Hooray for the changes, let’s hop and cheer,
For the future of blocks is looking quite clear! 🌟


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Outside diff range and nitpick comments (1)
models/block_test.go (1)

Line range hint 1-27: Ensure the fix is specific to Testnet Genesis blocks

While the new test covers the Testnet Genesis block hash calculation, it's important to verify that this fix doesn't unintentionally affect other network types or general block hashing. Consider adding the following:

  1. A test for Genesis blocks of other network types (e.g., Mainnet, Emulator) to ensure their hash calculations remain unchanged.
  2. A test to verify that non-Genesis blocks still include the PrevRandao field in their hash calculation.

Here are suggested additional tests:

func Test_GenesisBlockHashForOtherNetworks(t *testing.T) {
	networks := []flowGo.Chain{flowGo.Mainnet, flowGo.Emulator}
	for _, network := range networks {
		t.Run(string(network), func(t *testing.T) {
			block := GenesisBlock(network)
			blockHash, err := block.Hash()
			require.NoError(t, err)
			// Add assertions for expected hash values for each network
			// assert.Equal(t, expectedHashForNetwork, blockHash.String())
		})
	}
}

func Test_NonGenesisBlockIncludesPrevRandao(t *testing.T) {
	block := &Block{
		Block: &types.Block{
			Height:     1,
			PrevRandao: gethCommon.HexToHash("0x1234"),
		},
	}
	hash1, err := block.Hash()
	require.NoError(t, err)

	block.PrevRandao = gethCommon.HexToHash("0x5678")
	hash2, err := block.Hash()
	require.NoError(t, err)

	assert.NotEqual(t, hash1, hash2, "Changing PrevRandao should result in a different hash for non-Genesis blocks")
}

These additional tests will help ensure that the fix is specific to Testnet Genesis blocks and doesn't affect other scenarios.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 78467d5 and 4d70b64.

Files selected for processing (2)
  • models/block.go (1 hunks)
  • models/block_test.go (1 hunks)
Additional comments not posted (2)
models/block_test.go (1)

Line range hint 1-27: Overall assessment of the changes

The new test function Test_GenesisBlockHashForTestnet addresses the PR objective of fixing the Genesis block hash calculation for the Testnet network. However, to ensure a comprehensive and robust solution, consider implementing the following improvements:

  1. Enhance the existing test with better documentation and explicit verification of the PrevRandao field exclusion.
  2. Add tests for Genesis blocks of other network types to ensure the fix is specific to Testnet.
  3. Include a test for non-Genesis blocks to verify that PrevRandao is still included in their hash calculation.

These additions will provide better test coverage, clearer documentation, and ensure that the fix doesn't have unintended consequences on other parts of the system.

The current changes are a step in the right direction, but implementing the suggested improvements will greatly enhance the quality and reliability of this fix.

models/block.go (1)

22-47: Testnet Genesis block hash calculation logic is correctly implemented

The conditional logic introduced for the Testnet chain correctly recalculates the Genesis block hash without the PrevRandao field. This aligns with the PR objectives and ensures that the hash matches the expected value on Testnet.

models/block_test.go Outdated Show resolved Hide resolved
models/block.go Outdated Show resolved Hide resolved
@m-Peter m-Peter force-pushed the fix-genesis-block-hash-for-testnet branch from 2a4ca9c to ce27a36 Compare September 23, 2024 13:55
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Outside diff range and nitpick comments (2)
models/block.go (2)

23-34: LGTM: New variables for Testnet-specific handling.

The introduction of testnetEVMBlockExecutedEventID and testnetParentHashMapping is a good approach to handle Testnet-specific scenarios.

Consider adding a comment explaining why the specific block height (1385491) requires a manual mapping. This would improve code maintainability and help future developers understand the context.


Line range hint 1-238: Overall LGTM: Comprehensive changes for Testnet block hash calculation.

The modifications effectively address the PR objectives by implementing Testnet-specific handling for the Genesis block and subsequent block hash calculations. The changes are consistent and well-integrated into the existing codebase.

Consider adding a brief comment at the beginning of the file explaining the purpose of the Testnet-specific changes. This would provide helpful context for anyone reviewing or maintaining this file in the future.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 4d70b64 and 2a4ca9c.

Files selected for processing (1)
  • models/block.go (3 hunks)
Additional comments not posted (3)
models/block.go (3)

8-11: LGTM: New imports added.

The new import statements are appropriate for the changes made in this file.


37-62: LGTM: Genesis block handling for Testnet.

The changes to the GenesisBlock function correctly implement the exclusion of the PrevRandao field for the Testnet Genesis block, aligning with the PR objectives.

As mentioned in a previous review, please handle the error returned by blockV0.Hash(). This is important to ensure that any issues during hash calculation are caught and managed properly.


124-131: LGTM: Testnet-specific parent block hash handling.

The added conditional logic correctly updates the ParentBlockHash for specific Testnet block heights using the testnetParentHashMapping. This implementation aligns well with the PR objectives.

Copy link
Contributor

@ramtinms ramtinms left a comment

Choose a reason for hiding this comment

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

Do we have the same problem for the mainnet?

@m-Peter
Copy link
Collaborator Author

m-Peter commented Sep 23, 2024

Do we have the same problem for the mainnet?

Nope, this is just a problem on testnet. On mainnet, there have not been any hash calculation breaking changes.

models/block.go Outdated
@@ -80,6 +121,14 @@ func decodeBlockEvent(event cadence.Event) (*Block, error) {
return nil, fmt.Errorf("failed to cadence decode block [%s]: %w", event.String(), err)
}

if event.EventType.ID() == testnetEVMBlockExecutedEventID {
Copy link
Contributor

Choose a reason for hiding this comment

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

I would move this to block decoding from database on the model, not on the decoding of events

@m-Peter m-Peter force-pushed the fix-genesis-block-hash-for-testnet branch from ce27a36 to ec635fd Compare September 27, 2024 13:55
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (1)
storage/pebble/blocks.go (1)

284-298: Consider logging when adjusting the ParentBlockHash

Adding a log statement inside the conditional block can aid in debugging and monitoring. This will provide visibility when the ParentBlockHash is adjusted, which could be valuable for tracking the fix's application over time.

Apply this diff to add a debug log:

 if b.chainID == flowGo.Testnet && slices.Contains(testnetBrokenParentHashHeights, block.Height) {
+    log.Printf("Adjusting ParentBlockHash for block height: %d", block.Height)
     data, err := b.store.get(blockHeightKey, uint64Bytes(block.Height-1))
     if err != nil {
         return nil, fmt.Errorf("failed to get block: %w", err)
     }
     parentBlock, err := models.NewBlockFromBytes(data)
     if err != nil {
         return nil, err
     }
     parentBlockHash, err := parentBlock.Hash()
     if err != nil {
         return nil, err
     }
     block.ParentBlockHash = parentBlockHash
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between ce27a36 and ec635fd.

📒 Files selected for processing (1)
  • storage/pebble/blocks.go (3 hunks)
🔇 Additional comments (1)
storage/pebble/blocks.go (1)

23-26: Definition of testnetBrokenParentHashHeights is appropriate

The addition of testnetBrokenParentHashHeights correctly specifies the block heights with known parent hash issues on Testnet. This will help in addressing the inconsistencies observed in issue #534.

storage/pebble/blocks.go Show resolved Hide resolved
storage/pebble/blocks.go Outdated Show resolved Hide resolved
@j1010001
Copy link
Member

Needs an update from @m-Peter and then @ramtinms agrees we can merge

@j1010001 j1010001 requested a review from zhangchiqing as a code owner October 1, 2024 16:18
storage/pebble/blocks.go Outdated Show resolved Hide resolved
@m-Peter m-Peter force-pushed the fix-genesis-block-hash-for-testnet branch from 97bf80c to 7ba0544 Compare October 2, 2024 12:06
@m-Peter m-Peter force-pushed the fix-genesis-block-hash-for-testnet branch from 7ba0544 to f14ad0c Compare October 2, 2024 12:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: ✅ Done
Development

Successfully merging this pull request may close these issues.

Broken Chain in JSON rpc nodes with Flow-Testnet
7 participants