mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-12 09:51:36 +00:00
BinaryTrie.GetAccount returned the wrong account data for non-existent
addresses when the trie root was a StemNode (single-account trie). The
StemNode branch directly returned r.Values without verifying that the
queried address's stem matched the node's stem. Similarly, GetStorage
panicked via StemNode.Get("this should not be called directly") when
the root was a StemNode.
Additionally, Empty.GetValuesAtStem returned a non-nil slice of 256
nil entries instead of nil, creating a semantic trap for callers that
check values != nil to determine membership.
Fix all four bug sites:
1. StemNode.Get: replace panic with proper stem verification and value
lookup, matching InternalNode.Get's contract.
2. GetAccount StemNode branch: delegate to GetValuesAtStem (which
already has the stem equality check) instead of accessing r.Values
directly. This is consistent with the InternalNode branch.
3. Empty.GetValuesAtStem: return nil instead of 256 nil values.
Callers (InternalNode.Get, GetAccount) already handle nil correctly.
4. GetAccount: add explicit nil-values guard before the decode logic
as defense-in-depth, and simplify the now-redundant values != nil
condition in the emptyAccount loop.
73 lines
1.9 KiB
Go
73 lines
1.9 KiB
Go
// Copyright 2025 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 <http://www.gnu.org/licenses/>.
|
|
|
|
package bintrie
|
|
|
|
import (
|
|
"slices"
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
)
|
|
|
|
type Empty struct{}
|
|
|
|
func (e Empty) Get(_ []byte, _ NodeResolverFn) ([]byte, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
func (e Empty) Insert(key []byte, value []byte, _ NodeResolverFn, depth int) (BinaryNode, error) {
|
|
var values [256][]byte
|
|
values[key[31]] = value
|
|
return &StemNode{
|
|
Stem: slices.Clone(key[:31]),
|
|
Values: values[:],
|
|
depth: depth,
|
|
mustRecompute: true,
|
|
}, nil
|
|
}
|
|
|
|
func (e Empty) Copy() BinaryNode {
|
|
return Empty{}
|
|
}
|
|
|
|
func (e Empty) Hash() common.Hash {
|
|
return common.Hash{}
|
|
}
|
|
|
|
func (e Empty) GetValuesAtStem(_ []byte, _ NodeResolverFn) ([][]byte, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
func (e Empty) InsertValuesAtStem(key []byte, values [][]byte, _ NodeResolverFn, depth int) (BinaryNode, error) {
|
|
return &StemNode{
|
|
Stem: slices.Clone(key[:31]),
|
|
Values: values,
|
|
depth: depth,
|
|
mustRecompute: true,
|
|
}, nil
|
|
}
|
|
|
|
func (e Empty) CollectNodes(_ []byte, _ NodeFlushFn) error {
|
|
return nil
|
|
}
|
|
|
|
func (e Empty) toDot(parent string, path string) string {
|
|
return ""
|
|
}
|
|
|
|
func (e Empty) GetHeight() int {
|
|
return 0
|
|
}
|