diff --git a/core/vm/instructions.go b/core/vm/instructions.go index d05307427d..f43ab576c2 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -17,6 +17,8 @@ package vm import ( + "encoding/binary" + "github.com/holiman/uint256" "golang.org/x/crypto/sha3" @@ -440,13 +442,28 @@ func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ( } var upper, lower uint64 upper = interpreter.evm.Context.BlockNumber.Uint64() - if upper < 2 { + if upper < 257 { lower = 0 } else { - lower = upper - 1 + lower = upper - 256 } if num64 >= lower && num64 < upper { - num.SetBytes(interpreter.evm.Context.GetHash(num64).Bytes()) + chainId := interpreter.evm.ChainConfig().ChainID + chainIdBuf := make([]byte, 8) + binary.BigEndian.PutUint64(chainIdBuf, chainId.Uint64()) + num64Buf := make([]byte, 8) + binary.BigEndian.PutUint64(num64Buf, num64) + + if interpreter.hasher == nil { + interpreter.hasher = sha3.NewLegacyKeccak256().(keccakState) + } else { + interpreter.hasher.Reset() + } + interpreter.hasher.Write(chainIdBuf) + interpreter.hasher.Write(num64Buf) + interpreter.hasher.Read(interpreter.hasherBuf[:]) + + num.SetBytes(interpreter.hasherBuf[:]) } else { num.Clear() } diff --git a/core/vm/runtime/runtime_test.go b/core/vm/runtime/runtime_test.go index 6892e65d92..46f94a2195 100644 --- a/core/vm/runtime/runtime_test.go +++ b/core/vm/runtime/runtime_test.go @@ -334,11 +334,15 @@ func TestBlockhash(t *testing.T) { if zero.BitLen() != 0 { t.Fatalf("expected zeroes, got %x", ret[0:32]) } - if first.Uint64() != 999 { - t.Fatalf("second block should be 999, got %d (%x)", first, ret[32:64]) + firstExpectedHash := new(big.Int) + firstExpectedHash.SetString("13215081625009140218242111988507489764601005198286886925088730931502473149599", 10) + if first.Uint64() != firstExpectedHash.Uint64() { + t.Fatalf("first hash should be 13215081625009140218242111988507489764601005198286886925088730931502473149599, got %d (%x)", first, ret[32:64]) } - if last.Uint64() != 0 { - t.Fatalf("last block should be 0, got %d (%x)", last, ret[64:96]) + lastExpectedHash := new(big.Int) + lastExpectedHash.SetString("2851160567348483005169712516804956111111231427377973738952179767509712807467", 10) + if last.Uint64() != lastExpectedHash.Uint64() { + t.Fatalf("last hash should be 2851160567348483005169712516804956111111231427377973738952179767509712807467, got %d (%x)", last, ret[64:96]) } if exp, got := 0, chain.counter; exp != got { t.Errorf("suboptimal; too much chain iteration, expected %d, got %d", exp, got) diff --git a/params/version.go b/params/version.go index 8f6ff5ba46..b765b8e71f 100644 --- a/params/version.go +++ b/params/version.go @@ -24,7 +24,7 @@ import ( const ( VersionMajor = 4 // Major version component of the current release VersionMinor = 2 // Minor version component of the current release - VersionPatch = 0 // Patch version component of the current release + VersionPatch = 1 // Patch version component of the current release VersionMeta = "sepolia" // Version metadata to append to the version string )