Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

core/rawdb: reduce allocations in *key methods #33006

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

Open
MariusVanDerWijden wants to merge 2 commits into ethereum:master
base: master
Choose a base branch
Loading
from MariusVanDerWijden:rawdb-reduce-allocs-2
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions core/rawdb/accessors_chain.go
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ type NumberHash struct {
// This method considers both limits to be _inclusive_.
func ReadAllHashesInRange(db ethdb.Iteratee, first, last uint64) []*NumberHash {
var (
start = encodeBlockNumber(first)
start = encodeUint64(first)
keyLength = len(headerPrefix) + 8 + 32
hashes = make([]*NumberHash, 0, 1+last-first)
it = db.NewIterator(headerPrefix, start)
Expand Down Expand Up @@ -155,7 +155,7 @@ func ReadHeaderNumber(db ethdb.KeyValueReader, hash common.Hash) (uint64, bool)
// WriteHeaderNumber stores the hash->number mapping.
func WriteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
key := headerNumberKey(hash)
enc := encodeBlockNumber(number)
enc := encodeUint64(number)
if err := db.Put(key, enc); err != nil {
log.Crit("Failed to store hash to number mapping", "err", err)
}
Expand Down Expand Up @@ -272,7 +272,7 @@ func ReadTxIndexTail(db ethdb.KeyValueReader) *uint64 {
// WriteTxIndexTail stores the number of oldest indexed block
// into database.
func WriteTxIndexTail(db ethdb.KeyValueWriter, number uint64) {
if err := db.Put(txIndexTailKey, encodeBlockNumber(number)); err != nil {
if err := db.Put(txIndexTailKey, encodeUint64(number)); err != nil {
log.Crit("Failed to store the transaction index tail", "err", err)
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/rawdb/accessors_state.go
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func ReadPersistentStateID(db ethdb.KeyValueReader) uint64 {

// WritePersistentStateID stores the id of the persistent state into database.
func WritePersistentStateID(db ethdb.KeyValueWriter, number uint64) {
if err := db.Put(persistentStateIDKey, encodeBlockNumber(number)); err != nil {
if err := db.Put(persistentStateIDKey, encodeUint64(number)); err != nil {
log.Crit("Failed to store the persistent state ID", "err", err)
}
}
Expand Down
161 changes: 90 additions & 71 deletions core/rawdb/schema.go
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -177,80 +177,115 @@ type LegacyTxLookupEntry struct {
Index uint64
}

// encodeBlockNumber encodes a block number as big endian uint64
func encodeBlockNumber(number uint64) []byte {
// encodeUint64 encodes a block number as big endian uint64
func encodeUint64(number uint64) []byte {
enc := make([]byte, 8)
binary.BigEndian.PutUint64(enc, number)
return enc
}

func encodeUint32(number uint32) []byte {
enc := make([]byte, 4)
binary.BigEndian.PutUint32(enc, number)
return enc
}

func encodeKey(input []byte, values ...[]byte) []byte {
off := 0
for _, h := range values {
off += copy(input[off:], h)
}
return input
}

// headerKeyPrefix = headerPrefix + num (uint64 big endian)
func headerKeyPrefix(number uint64) []byte {
return append(headerPrefix, encodeBlockNumber(number)...)
// len(headerPrefix) + len(uint64)
buf := make([]byte, 1+8)
return encodeKey(buf, headerPrefix, encodeUint64(number))
}

// headerKey = headerPrefix + num (uint64 big endian) + hash
func headerKey(number uint64, hash common.Hash) []byte {
return append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...)
// len(headerPrefix) + len(uint64) + len(hash)
buf := make([]byte, 1+8+common.HashLength)
return encodeKey(buf, headerPrefix, encodeUint64(number), hash.Bytes())
}

// headerHashKey = headerPrefix + num (uint64 big endian) + headerHashSuffix
func headerHashKey(number uint64) []byte {
return append(append(headerPrefix, encodeBlockNumber(number)...), headerHashSuffix...)
// len(headerPrefix) + len(uint64) + len(headerHashSuffix)
buf := make([]byte, 1+8+1)
return encodeKey(buf, headerPrefix, encodeUint64(number), headerHashSuffix)
}

// headerNumberKey = headerNumberPrefix + hash
func headerNumberKey(hash common.Hash) []byte {
return append(headerNumberPrefix, hash.Bytes()...)
buf := make([]byte, 1+common.HashLength)
return encodeKey(buf, headerNumberPrefix, hash.Bytes())
}

// blockBodyKey = blockBodyPrefix + num (uint64 big endian) + hash
func blockBodyKey(number uint64, hash common.Hash) []byte {
return append(append(blockBodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...)
// len(blockBodyPrefix) + len(uint64) + len(hash)
buf := make([]byte, 1+8+common.HashLength)
return encodeKey(buf, blockBodyPrefix, encodeUint64(number), hash.Bytes())
}

// blockReceiptsKey = blockReceiptsPrefix + num (uint64 big endian) + hash
func blockReceiptsKey(number uint64, hash common.Hash) []byte {
return append(append(blockReceiptsPrefix, encodeBlockNumber(number)...), hash.Bytes()...)
// len(blockReceiptsPrefix) + len(uint64) + len(hash)
buf := make([]byte, 1+8+common.HashLength)
return encodeKey(buf, blockReceiptsPrefix, encodeUint64(number), hash.Bytes())
}

// txLookupKey = txLookupPrefix + hash
func txLookupKey(hash common.Hash) []byte {
return append(txLookupPrefix, hash.Bytes()...)
// len(txLookupPrefix) + len(hash)
buf := make([]byte, 1+common.HashLength)
return encodeKey(buf, txLookupPrefix, hash.Bytes())
}

// accountSnapshotKey = SnapshotAccountPrefix + hash
func accountSnapshotKey(hash common.Hash) []byte {
return append(SnapshotAccountPrefix, hash.Bytes()...)
// len(SnapshotAccountPrefix) + len(hash)
buf := make([]byte, 1+common.HashLength)
return encodeKey(buf, SnapshotAccountPrefix, hash.Bytes())
}

// storageSnapshotKey = SnapshotStoragePrefix + account hash + storage hash
func storageSnapshotKey(accountHash, storageHash common.Hash) []byte {
buf := make([]byte, len(SnapshotStoragePrefix)+common.HashLength+common.HashLength)
n := copy(buf, SnapshotStoragePrefix)
n += copy(buf[n:], accountHash.Bytes())
copy(buf[n:], storageHash.Bytes())
return buf
//len(SnapshotStoragePrefix) + len(accountHash) + len(storageHash)
buf := make([]byte, 1+common.HashLength+common.HashLength)
return encodeKey(buf, SnapshotStoragePrefix, accountHash.Bytes(), storageHash.Bytes())
}

// storageSnapshotsKey = SnapshotStoragePrefix + account hash + storage hash
// storageSnapshotsKey = SnapshotStoragePrefix + account hash
func storageSnapshotsKey(accountHash common.Hash) []byte {
return append(SnapshotStoragePrefix, accountHash.Bytes()...)
// len(SnapshotStoragePrefix) + len(accountHash)
buf := make([]byte, 1+common.HashLength)
return encodeKey(buf, SnapshotStoragePrefix, accountHash.Bytes())
}

// skeletonHeaderKey = skeletonHeaderPrefix + num (uint64 big endian)
func skeletonHeaderKey(number uint64) []byte {
return append(skeletonHeaderPrefix, encodeBlockNumber(number)...)
// len(skeletonHeaderPrefix) + len(uint64)
buf := make([]byte, 1+8)
return encodeKey(buf, skeletonHeaderPrefix, encodeUint64(number))
}

// preimageKey = PreimagePrefix + hash
func preimageKey(hash common.Hash) []byte {
return append(PreimagePrefix, hash.Bytes()...)
// len(PreimagePrefix) + len(hash)
buf := make([]byte, 11+common.HashLength)
return encodeKey(buf, PreimagePrefix, hash.Bytes())
}

// codeKey = CodePrefix + hash
func codeKey(hash common.Hash) []byte {
return append(CodePrefix, hash.Bytes()...)
// len(CodePrefix) + len(hash)
buf := make([]byte, 1+common.HashLength)
return encodeKey(buf, CodePrefix, hash.Bytes())
}

// IsCodeKey reports whether the given byte slice is the key of contract code,
Expand All @@ -264,17 +299,23 @@ func IsCodeKey(key []byte) (bool, []byte) {

// configKey = configPrefix + hash
func configKey(hash common.Hash) []byte {
return append(configPrefix, hash.Bytes()...)
// len(configPrefix) + len(hash)
buf := make([]byte, 16+common.HashLength)
return encodeKey(buf, configPrefix, hash.Bytes())
}

// genesisStateSpecKey = genesisPrefix + hash
func genesisStateSpecKey(hash common.Hash) []byte {
return append(genesisPrefix, hash.Bytes()...)
// len(genesisPrefix) + len(hash)
buf := make([]byte, 17+common.HashLength)
return encodeKey(buf, genesisPrefix, hash.Bytes())
}

// stateIDKey = stateIDPrefix + root (32 bytes)
func stateIDKey(root common.Hash) []byte {
return append(stateIDPrefix, root.Bytes()...)
// len(stateIDPrefix) + len(root)
buf := make([]byte, 1+common.HashLength)
return encodeKey(buf, stateIDPrefix, root.Bytes())
}

// accountTrieNodeKey = TrieNodeAccountPrefix + nodePath.
Expand Down Expand Up @@ -352,53 +393,42 @@ func IsStorageTrieNode(key []byte) bool {
return ok
}

// filterMapRowKey = filterMapRowPrefix + mapRowIndex (uint64 big endian)
func filterMapRowKey(mapRowIndex uint64, base bool) []byte {
extLen := 8
if base {
extLen = 9
// len(filterMapRowPrefix) + extLen
key := make([]byte, 4+9)
key = encodeKey(key, filterMapRowPrefix, encodeUint64(mapRowIndex))
if !base {
return key[0 : 4+8]
}
l := len(filterMapRowPrefix)
key := make([]byte, l+extLen)
copy(key[:l], filterMapRowPrefix)
binary.BigEndian.PutUint64(key[l:l+8], mapRowIndex)
return key
}

// filterMapLastBlockKey = filterMapLastBlockPrefix + mapIndex (uint32 big endian)
func filterMapLastBlockKey(mapIndex uint32) []byte {
l := len(filterMapLastBlockPrefix)
key := make([]byte, l+4)
copy(key[:l], filterMapLastBlockPrefix)
binary.BigEndian.PutUint32(key[l:], mapIndex)
return key
// len(filterMapLastBlockPrefix) + len(uint32)
key := make([]byte, 4+4)
return encodeKey(key, filterMapLastBlockPrefix, encodeUint32(mapIndex))
}

// filterMapBlockLVKey = filterMapBlockLVPrefix + num (uint64 big endian)
func filterMapBlockLVKey(number uint64) []byte {
l := len(filterMapBlockLVPrefix)
key := make([]byte, l+8)
copy(key[:l], filterMapBlockLVPrefix)
binary.BigEndian.PutUint64(key[l:], number)
return key
//len(filterMapBlockLVPrefix) + len(uint64)
key := make([]byte, 4+8)
return encodeKey(key, filterMapBlockLVPrefix, encodeUint64(number))
}

// accountHistoryIndexKey = StateHistoryAccountMetadataPrefix + addressHash
func accountHistoryIndexKey(addressHash common.Hash) []byte {
return append(StateHistoryAccountMetadataPrefix, addressHash.Bytes()...)
// len(StateHistoryAccountMetadataPrefix) + len(addressHash)
buf := make([]byte, 2+common.HashLength)
return encodeKey(buf, StateHistoryAccountMetadataPrefix, addressHash.Bytes())
}

// storageHistoryIndexKey = StateHistoryStorageMetadataPrefix + addressHash + storageHash
func storageHistoryIndexKey(addressHash common.Hash, storageHash common.Hash) []byte {
totalLen := len(StateHistoryStorageMetadataPrefix) + 2*common.HashLength
out := make([]byte, totalLen)

off := 0
off += copy(out[off:], StateHistoryStorageMetadataPrefix)
off += copy(out[off:], addressHash.Bytes())
copy(out[off:], storageHash.Bytes())

return out
// len(StateHistoryStorageMetadataPrefix) + len(addressHash) + len(storageHash)
out := make([]byte, 2+2*common.HashLength)
return encodeKey(out, StateHistoryStorageMetadataPrefix, addressHash.Bytes(), storageHash.Bytes())
}

// trienodeHistoryIndexKey = TrienodeHistoryMetadataPrefix + addressHash + trienode path
Expand All @@ -416,29 +446,16 @@ func trienodeHistoryIndexKey(addressHash common.Hash, path []byte) []byte {

// accountHistoryIndexBlockKey = StateHistoryAccountBlockPrefix + addressHash + blockID
func accountHistoryIndexBlockKey(addressHash common.Hash, blockID uint32) []byte {
totalLen := len(StateHistoryAccountBlockPrefix) + common.HashLength + 4
out := make([]byte, totalLen)

off := 0
off += copy(out[off:], StateHistoryAccountBlockPrefix)
off += copy(out[off:], addressHash.Bytes())
binary.BigEndian.PutUint32(out[off:], blockID)

return out
// len(StateHistoryAccountBlockPrefix) + len(common.Hash) + len(uint32)
out := make([]byte, 3+common.HashLength+4)
return encodeKey(out, StateHistoryAccountBlockPrefix, addressHash.Bytes(), encodeUint32(blockID))
}

// storageHistoryIndexBlockKey = StateHistoryStorageBlockPrefix + addressHash + storageHash + blockID
func storageHistoryIndexBlockKey(addressHash common.Hash, storageHash common.Hash, blockID uint32) []byte {
totalLen := len(StateHistoryStorageBlockPrefix) + 2*common.HashLength + 4
out := make([]byte, totalLen)

off := 0
off += copy(out[off:], StateHistoryStorageBlockPrefix)
off += copy(out[off:], addressHash.Bytes())
off += copy(out[off:], storageHash.Bytes())
binary.BigEndian.PutUint32(out[off:], blockID)

return out
// len(StateHistoryStorageBlockPrefix) + 2*common.HashLength + len(uint32)
out := make([]byte, 3+2*common.HashLength+4)
return encodeKey(out, StateHistoryStorageBlockPrefix, addressHash.Bytes(), storageHash.Bytes(), encodeUint32(blockID))
}

// trienodeHistoryIndexBlockKey = TrienodeHistoryBlockPrefix + addressHash + trienode path + blockID
Expand All @@ -457,5 +474,7 @@ func trienodeHistoryIndexBlockKey(addressHash common.Hash, path []byte, blockID

// transitionStateKey = transitionStatusKey + hash
func transitionStateKey(hash common.Hash) []byte {
return append(VerkleTransitionStatePrefix, hash.Bytes()...)
// len(VerkleTransitionStatePrefix) + len(hash)
buf := make([]byte, 24+common.HashLength)
return encodeKey(buf, VerkleTransitionStatePrefix, hash.Bytes())
}

AltStyle によって変換されたページ (->オリジナル) /