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

Calculated hash for fetched block is wrong [go-ethereum] #719

Open
nvdtf opened this issue Jan 9, 2025 · 3 comments
Open

Calculated hash for fetched block is wrong [go-ethereum] #719

nvdtf opened this issue Jan 9, 2025 · 3 comments
Assignees
Labels
Bug Something isn't working Feedback

Comments

@nvdtf
Copy link
Member

nvdtf commented Jan 9, 2025

Problem

There seems to be an issue with fetching blocks from the Flow network. eth_getBlockByNumber returns the correct hash but go-ethereum tries to calculate block hashes locally and ends up with a different one.

Steps to Reproduce

This code reproduces the issue:

package main

import (
	"context"
	"fmt"
	"math/big"

	"github.com/ethereum/go-ethereum/ethclient"
)

func main() {
	DoTest("https://sepolia.infura.io/v3/xxx")
	DoTest("https://testnet.evm.nodes.onflow.org")
}

func DoTest(endpoint string) {
	ctx := context.Background()
	fmt.Printf("-------- %s --------\n", endpoint)
	client, err := ethclient.Dial(endpoint)
	if err != nil {
		panic(err)
	}

	// fetch latest block height
	blockNo, err := client.BlockNumber(ctx)
	if err != nil {
		panic(err)
	}
	fmt.Println("Latest Block Height: ", blockNo)

	// fetch latest block by number
	block, err := client.BlockByNumber(ctx, big.NewInt(int64(blockNo)))
	if err != nil {
		panic(err)
	}
	fmt.Println("BlockByNumber: ", block.Hash())

	// now fetch same block by hash
	// succeeds on sepolia, fails on Flow
	block2, err := client.BlockByHash(ctx, block.Hash())
	if err != nil {
		panic(err)
	}
	fmt.Println("BlockByHash: ", block2.Hash())
}

Output:

-------- https://sepolia.infura.io/v3/xx --------
Latest Block Height:  7456663
BlockByNumber:  0x0e987708a6c6c524b91c7203cecea4156e5fbb49b8e017b731639829d9db1141
BlockByHash:  0x0e987708a6c6c524b91c7203cecea4156e5fbb49b8e017b731639829d9db1141
-------- https://testnet.evm.nodes.onflow.org --------
Latest Block Height:  25531317
BlockByNumber:  0x06d21c45bfcfdd3b420f0cac7b93b75ec10f01b2d4902fdfd449251b1c18d2bb
panic: not found

The correct block hash for the above height (25531317) is 0x1ca014b7d9dd67e93d777bc5c94a1f1be8be9017375aae94e1abc6240986d0cf Explorer

Acceptance Criteria

Flow behaviour should match Sepolia. go-ethereum should be able to calculate the correct block hash and eth_getBlockByHash call above should succeed.

@nvdtf nvdtf added Feedback Bug Something isn't working labels Jan 9, 2025
@nvdtf
Copy link
Member Author

nvdtf commented Jan 9, 2025

I encountered the same problem with transaction hashes:

package main

import (
	"context"
	"fmt"

	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/ethclient"
)

func main() {
	DoTest("https://sepolia.infura.io/v3/xx", "0x6e75a5cf4d4260a036d4722dd3eb5cf184dcaeb4e12c8e977589a4ee70a69c41", 0)
	// https://evm-testnet.flowscan.io/block/0x868ef12b3bc5079c39960ac510835f186bdf0a00f33a0afe60d47c59d2777691?tab=txs
	// will fail due to wrong hash calc
	// correct hash is 0xc92affd12a71f201e7f1bf34a56500114c480918856e574fa6577ee172a9a226
	DoTest("https://testnet.evm.nodes.onflow.org", "0x868ef12b3bc5079c39960ac510835f186bdf0a00f33a0afe60d47c59d2777691", 0)
}

func DoTest(endpoint string, blockHash string, txIndex uint) {
	ctx := context.Background()
	fmt.Printf("-------- %s --------\n", endpoint)
	client, err := ethclient.Dial(endpoint)
	if err != nil {
		panic(err)
	}

	tx, err := client.TransactionInBlock(ctx, common.HexToHash(blockHash), txIndex)
	if err != nil {
		panic(err)
	}
	fmt.Println(tx.Hash())

	receipt, err := client.TransactionReceipt(ctx, tx.Hash())
	if err != nil {
		panic(err)
	}
	fmt.Println(receipt.Status)
}

Output:

-------- https://sepolia.infura.io/v3/xxx --------
0x1e135bbedfd719b24fc816ee890c7d929b6cc63c8166bf7db697afefce2fac5a
1
-------- https://testnet.evm.nodes.onflow.org --------
0xf4d0e7a48e8fc3cb3681a2a387a90fe2179a4c80122d5a112bfe4500229eaae6
panic: not found

@m-Peter m-Peter self-assigned this Jan 10, 2025
@bluesign
Copy link

bluesign commented Jan 10, 2025

how flow-evm block is structured is different than how go-ethereum block is AFAIK, I don't think it can ever match. ( for old blocks ) but ofc hash calculation can be changed for newer ones.

@m-Peter
Copy link
Collaborator

m-Peter commented Jan 10, 2025

Regarding the block hash calculation, Flow EVM has its own Block type, with its own fields, which also affects the hash calculation. It might be possible to make it match the hash calculation from go-ethereum, but that will be a breaking change, and it's not very trivial.

Regarding the tx hash calculation, the example listed above, involves a transaction that is formed from a direct call (originated from a COA). See the from in https://evm-testnet.flowscan.io/tx/0xc92affd12a71f201e7f1bf34a56500114c480918856e574fa6577ee172a9a226, which is equal to 0x0000000000000000000000020000000000000000.
For direct calls, Flow EVM also has its own hash calculation, that's why the ethclient could not find it.

I tried with a regular EVM transaction (https://evm-testnet.flowscan.io/tx/0x919b5c3edf188bcfa149a102120d81389195b1fc498bd4ba64ff0ebc4a8f68d3), and the ethclient was able to find it.

Update: We could try to update our fork of go-ethereum, located here: https://github.com/onflow/go-ethereum . We could also try to update the original ethclient to simply rely on the payload fields returned by the JSON-RPC endpoints, instead of re-calculating the block/tx hashes. Not sure how welcome are contributions on the original go-ethereum repo 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something isn't working Feedback
Projects
None yet
Development

No branches or pull requests

3 participants