diff --git a/core/rawdb/schema.go b/core/rawdb/schema.go index d9140c5fd6..981adbdd61 100644 --- a/core/rawdb/schema.go +++ b/core/rawdb/schema.go @@ -186,17 +186,30 @@ func encodeBlockNumber(number uint64) []byte { // headerKeyPrefix = headerPrefix + num (uint64 big endian) func headerKeyPrefix(number uint64) []byte { - return append(headerPrefix, encodeBlockNumber(number)...) + buf := make([]byte, len(headerPrefix)+8) + copy(buf, headerPrefix) + binary.BigEndian.PutUint64(buf[len(headerPrefix):], number) + return buf } // headerKey = headerPrefix + num (uint64 big endian) + hash func headerKey(number uint64, hash common.Hash) []byte { - return append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...) + buf := make([]byte, len(headerPrefix)+8+common.HashLength) + n := copy(buf, headerPrefix) + binary.BigEndian.PutUint64(buf[n:], number) + n += 8 + copy(buf[n:], hash.Bytes()) + return buf } // headerHashKey = headerPrefix + num (uint64 big endian) + headerHashSuffix func headerHashKey(number uint64) []byte { - return append(append(headerPrefix, encodeBlockNumber(number)...), headerHashSuffix...) + buf := make([]byte, len(headerPrefix)+8+len(headerHashSuffix)) + n := copy(buf, headerPrefix) + binary.BigEndian.PutUint64(buf[n:], number) + n += 8 + copy(buf[n:], headerHashSuffix) + return buf } // headerNumberKey = headerNumberPrefix + hash @@ -206,12 +219,22 @@ func headerNumberKey(hash common.Hash) []byte { // blockBodyKey = blockBodyPrefix + num (uint64 big endian) + hash func blockBodyKey(number uint64, hash common.Hash) []byte { - return append(append(blockBodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...) + buf := make([]byte, len(blockBodyPrefix)+8+common.HashLength) + n := copy(buf, blockBodyPrefix) + binary.BigEndian.PutUint64(buf[n:], number) + n += 8 + copy(buf[n:], hash.Bytes()) + return buf } // blockReceiptsKey = blockReceiptsPrefix + num (uint64 big endian) + hash func blockReceiptsKey(number uint64, hash common.Hash) []byte { - return append(append(blockReceiptsPrefix, encodeBlockNumber(number)...), hash.Bytes()...) + buf := make([]byte, len(blockReceiptsPrefix)+8+common.HashLength) + n := copy(buf, blockReceiptsPrefix) + binary.BigEndian.PutUint64(buf[n:], number) + n += 8 + copy(buf[n:], hash.Bytes()) + return buf } // txLookupKey = txLookupPrefix + hash @@ -240,7 +263,10 @@ func storageSnapshotsKey(accountHash common.Hash) []byte { // skeletonHeaderKey = skeletonHeaderPrefix + num (uint64 big endian) func skeletonHeaderKey(number uint64) []byte { - return append(skeletonHeaderPrefix, encodeBlockNumber(number)...) + buf := make([]byte, len(skeletonHeaderPrefix)+8) + copy(buf, skeletonHeaderPrefix) + binary.BigEndian.PutUint64(buf[len(skeletonHeaderPrefix):], number) + return buf } // preimageKey = PreimagePrefix + hash diff --git a/core/rawdb/schema_test.go b/core/rawdb/schema_test.go new file mode 100644 index 0000000000..f25b2b95c2 --- /dev/null +++ b/core/rawdb/schema_test.go @@ -0,0 +1,74 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rawdb + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common" +) + +var benchHash = common.HexToHash("0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef") + +func BenchmarkHeaderKey(b *testing.B) { + b.ReportAllocs() + for b.Loop() { + headerKey(123456789, benchHash) + } +} + +func BenchmarkHeaderHashKey(b *testing.B) { + b.ReportAllocs() + for b.Loop() { + headerHashKey(123456789) + } +} + +func BenchmarkHeaderKeyPrefix(b *testing.B) { + b.ReportAllocs() + for b.Loop() { + headerKeyPrefix(123456789) + } +} + +func BenchmarkBlockBodyKey(b *testing.B) { + b.ReportAllocs() + for b.Loop() { + blockBodyKey(123456789, benchHash) + } +} + +func BenchmarkBlockReceiptsKey(b *testing.B) { + b.ReportAllocs() + for b.Loop() { + blockReceiptsKey(123456789, benchHash) + } +} + +func BenchmarkSkeletonHeaderKey(b *testing.B) { + b.ReportAllocs() + for b.Loop() { + skeletonHeaderKey(123456789) + } +} + +func BenchmarkEncodeBlockNumber(b *testing.B) { + b.ReportAllocs() + for b.Loop() { + encodeBlockNumber(123456789) + } +}