mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-23 05:06:43 +00:00
core, triedb: address comments from marius
This commit is contained in:
parent
507c50d572
commit
6ab502d302
3 changed files with 34 additions and 32 deletions
|
|
@ -416,25 +416,19 @@ func trienodeHistoryIndexKey(addressHash common.Hash, path []byte) []byte {
|
||||||
|
|
||||||
// accountHistoryIndexBlockKey = StateHistoryAccountBlockPrefix + addressHash + blockID
|
// accountHistoryIndexBlockKey = StateHistoryAccountBlockPrefix + addressHash + blockID
|
||||||
func accountHistoryIndexBlockKey(addressHash common.Hash, blockID uint32) []byte {
|
func accountHistoryIndexBlockKey(addressHash common.Hash, blockID uint32) []byte {
|
||||||
var buf4 [4]byte
|
|
||||||
binary.BigEndian.PutUint32(buf4[:], blockID)
|
|
||||||
|
|
||||||
totalLen := len(StateHistoryAccountBlockPrefix) + common.HashLength + 4
|
totalLen := len(StateHistoryAccountBlockPrefix) + common.HashLength + 4
|
||||||
out := make([]byte, totalLen)
|
out := make([]byte, totalLen)
|
||||||
|
|
||||||
off := 0
|
off := 0
|
||||||
off += copy(out[off:], StateHistoryAccountBlockPrefix)
|
off += copy(out[off:], StateHistoryAccountBlockPrefix)
|
||||||
off += copy(out[off:], addressHash.Bytes())
|
off += copy(out[off:], addressHash.Bytes())
|
||||||
copy(out[off:], buf4[:])
|
binary.BigEndian.PutUint32(out[off:], blockID)
|
||||||
|
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
// storageHistoryIndexBlockKey = StateHistoryStorageBlockPrefix + addressHash + storageHash + blockID
|
// storageHistoryIndexBlockKey = StateHistoryStorageBlockPrefix + addressHash + storageHash + blockID
|
||||||
func storageHistoryIndexBlockKey(addressHash common.Hash, storageHash common.Hash, blockID uint32) []byte {
|
func storageHistoryIndexBlockKey(addressHash common.Hash, storageHash common.Hash, blockID uint32) []byte {
|
||||||
var buf4 [4]byte
|
|
||||||
binary.BigEndian.PutUint32(buf4[:], blockID)
|
|
||||||
|
|
||||||
totalLen := len(StateHistoryStorageBlockPrefix) + 2*common.HashLength + 4
|
totalLen := len(StateHistoryStorageBlockPrefix) + 2*common.HashLength + 4
|
||||||
out := make([]byte, totalLen)
|
out := make([]byte, totalLen)
|
||||||
|
|
||||||
|
|
@ -442,16 +436,13 @@ func storageHistoryIndexBlockKey(addressHash common.Hash, storageHash common.Has
|
||||||
off += copy(out[off:], StateHistoryStorageBlockPrefix)
|
off += copy(out[off:], StateHistoryStorageBlockPrefix)
|
||||||
off += copy(out[off:], addressHash.Bytes())
|
off += copy(out[off:], addressHash.Bytes())
|
||||||
off += copy(out[off:], storageHash.Bytes())
|
off += copy(out[off:], storageHash.Bytes())
|
||||||
copy(out[off:], buf4[:])
|
binary.BigEndian.PutUint32(out[off:], blockID)
|
||||||
|
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
// trienodeHistoryIndexBlockKey = TrienodeHistoryBlockPrefix + addressHash + trienode path + blockID
|
// trienodeHistoryIndexBlockKey = TrienodeHistoryBlockPrefix + addressHash + trienode path + blockID
|
||||||
func trienodeHistoryIndexBlockKey(addressHash common.Hash, path []byte, blockID uint32) []byte {
|
func trienodeHistoryIndexBlockKey(addressHash common.Hash, path []byte, blockID uint32) []byte {
|
||||||
var buf4 [4]byte
|
|
||||||
binary.BigEndian.PutUint32(buf4[:], blockID)
|
|
||||||
|
|
||||||
totalLen := len(TrienodeHistoryBlockPrefix) + common.HashLength + len(path) + 4
|
totalLen := len(TrienodeHistoryBlockPrefix) + common.HashLength + len(path) + 4
|
||||||
out := make([]byte, totalLen)
|
out := make([]byte, totalLen)
|
||||||
|
|
||||||
|
|
@ -459,7 +450,7 @@ func trienodeHistoryIndexBlockKey(addressHash common.Hash, path []byte, blockID
|
||||||
off += copy(out[off:], TrienodeHistoryBlockPrefix)
|
off += copy(out[off:], TrienodeHistoryBlockPrefix)
|
||||||
off += copy(out[off:], addressHash.Bytes())
|
off += copy(out[off:], addressHash.Bytes())
|
||||||
off += copy(out[off:], path)
|
off += copy(out[off:], path)
|
||||||
copy(out[off:], buf4[:])
|
binary.BigEndian.PutUint32(out[off:], blockID)
|
||||||
|
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -160,10 +160,7 @@ func newTrienodeHistory(root common.Hash, parent common.Hash, block uint64, node
|
||||||
|
|
||||||
// sharedLen returns the length of the common prefix shared by a and b.
|
// sharedLen returns the length of the common prefix shared by a and b.
|
||||||
func sharedLen(a, b []byte) int {
|
func sharedLen(a, b []byte) int {
|
||||||
n := len(a)
|
n := min(len(a), len(b))
|
||||||
if len(b) < n {
|
|
||||||
n = len(b)
|
|
||||||
}
|
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
if a[i] != b[i] {
|
if a[i] != b[i] {
|
||||||
return i
|
return i
|
||||||
|
|
@ -259,7 +256,8 @@ func (h *trienodeHistory) encode() ([]byte, []byte, []byte, error) {
|
||||||
internalValOffset += uint32(len(value))
|
internalValOffset += uint32(len(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode trailer
|
// Encode trailer, the number of restart sections is len(restarts))/2,
|
||||||
|
// as we track the offsets of both key and value sections.
|
||||||
var trailer []byte
|
var trailer []byte
|
||||||
for _, number := range append(restarts, uint32(len(restarts))/2) {
|
for _, number := range append(restarts, uint32(len(restarts))/2) {
|
||||||
binary.BigEndian.PutUint32(buf[:4], number)
|
binary.BigEndian.PutUint32(buf[:4], number)
|
||||||
|
|
@ -341,7 +339,7 @@ func decodeSingle(keySection []byte, onValue func([]byte, int, int) error) ([]st
|
||||||
|
|
||||||
keys []string
|
keys []string
|
||||||
)
|
)
|
||||||
// Decode restarts
|
// Decode the number of restart section
|
||||||
if len(keySection) < 4 {
|
if len(keySection) < 4 {
|
||||||
return nil, fmt.Errorf("key section too short, size: %d", len(keySection))
|
return nil, fmt.Errorf("key section too short, size: %d", len(keySection))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,11 +43,9 @@ func randomTrienodes(n int) (map[common.Hash]map[string][]byte, common.Hash) {
|
||||||
nodes[owner] = make(map[string][]byte)
|
nodes[owner] = make(map[string][]byte)
|
||||||
|
|
||||||
for j := 0; j < 10; j++ {
|
for j := 0; j < 10; j++ {
|
||||||
pathLen := rand.Intn(10)
|
path := testrand.Bytes(rand.Intn(10))
|
||||||
path := testrand.Bytes(pathLen)
|
|
||||||
for z := 0; z < len(path); z++ {
|
for z := 0; z < len(path); z++ {
|
||||||
valLen := rand.Intn(128)
|
nodes[owner][string(path[:z])] = testrand.Bytes(rand.Intn(128))
|
||||||
nodes[owner][string(path[:z])] = testrand.Bytes(valLen)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// zero-size trie node, representing it was non-existent before
|
// zero-size trie node, representing it was non-existent before
|
||||||
|
|
@ -65,7 +63,7 @@ func randomTrienodes(n int) (map[common.Hash]map[string][]byte, common.Hash) {
|
||||||
return nodes, root
|
return nodes, root
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeTrinodeHistory() *trienodeHistory {
|
func makeTrienodeHistory() *trienodeHistory {
|
||||||
nodes, root := randomTrienodes(10)
|
nodes, root := randomTrienodes(10)
|
||||||
return newTrienodeHistory(root, common.Hash{}, 1, nodes)
|
return newTrienodeHistory(root, common.Hash{}, 1, nodes)
|
||||||
}
|
}
|
||||||
|
|
@ -86,7 +84,7 @@ func makeTrienodeHistories(n int) []*trienodeHistory {
|
||||||
func TestEncodeDecodeTrienodeHistory(t *testing.T) {
|
func TestEncodeDecodeTrienodeHistory(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
dec trienodeHistory
|
dec trienodeHistory
|
||||||
obj = makeTrinodeHistory()
|
obj = makeTrienodeHistory()
|
||||||
)
|
)
|
||||||
header, keySection, valueSection, err := obj.encode()
|
header, keySection, valueSection, err := obj.encode()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -108,6 +106,21 @@ func TestEncodeDecodeTrienodeHistory(t *testing.T) {
|
||||||
if !compareMapSet(dec.nodes, obj.nodes) {
|
if !compareMapSet(dec.nodes, obj.nodes) {
|
||||||
t.Fatal("trienode content is mismatched")
|
t.Fatal("trienode content is mismatched")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Re-encode again, ensuring the encoded blob still match
|
||||||
|
header2, keySection2, valueSection2, err := dec.encode()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to encode trienode history: %v", err)
|
||||||
|
}
|
||||||
|
if !bytes.Equal(header, header2) {
|
||||||
|
t.Fatal("re-encoded header is mismatched")
|
||||||
|
}
|
||||||
|
if !bytes.Equal(keySection, keySection2) {
|
||||||
|
t.Fatal("re-encoded key section is mismatched")
|
||||||
|
}
|
||||||
|
if !bytes.Equal(valueSection, valueSection2) {
|
||||||
|
t.Fatal("re-encoded value section is mismatched")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTrienodeHistoryReader(t *testing.T) {
|
func TestTrienodeHistoryReader(t *testing.T) {
|
||||||
|
|
@ -280,7 +293,7 @@ func TestNilNodeValues(t *testing.T) {
|
||||||
|
|
||||||
// TestCorruptedHeader tests error handling for corrupted header data
|
// TestCorruptedHeader tests error handling for corrupted header data
|
||||||
func TestCorruptedHeader(t *testing.T) {
|
func TestCorruptedHeader(t *testing.T) {
|
||||||
h := makeTrinodeHistory()
|
h := makeTrienodeHistory()
|
||||||
header, keySection, valueSection, _ := h.encode()
|
header, keySection, valueSection, _ := h.encode()
|
||||||
|
|
||||||
// Test corrupted version
|
// Test corrupted version
|
||||||
|
|
@ -311,7 +324,7 @@ func TestCorruptedHeader(t *testing.T) {
|
||||||
|
|
||||||
// TestCorruptedKeySection tests error handling for corrupted key section data
|
// TestCorruptedKeySection tests error handling for corrupted key section data
|
||||||
func TestCorruptedKeySection(t *testing.T) {
|
func TestCorruptedKeySection(t *testing.T) {
|
||||||
h := makeTrinodeHistory()
|
h := makeTrienodeHistory()
|
||||||
header, keySection, valueSection, _ := h.encode()
|
header, keySection, valueSection, _ := h.encode()
|
||||||
|
|
||||||
// Test empty key section when header indicates data
|
// Test empty key section when header indicates data
|
||||||
|
|
@ -345,7 +358,7 @@ func TestCorruptedKeySection(t *testing.T) {
|
||||||
|
|
||||||
// TestCorruptedValueSection tests error handling for corrupted value section data
|
// TestCorruptedValueSection tests error handling for corrupted value section data
|
||||||
func TestCorruptedValueSection(t *testing.T) {
|
func TestCorruptedValueSection(t *testing.T) {
|
||||||
h := makeTrinodeHistory()
|
h := makeTrienodeHistory()
|
||||||
header, keySection, valueSection, _ := h.encode()
|
header, keySection, valueSection, _ := h.encode()
|
||||||
|
|
||||||
// Test truncated value section
|
// Test truncated value section
|
||||||
|
|
@ -368,7 +381,7 @@ func TestCorruptedValueSection(t *testing.T) {
|
||||||
|
|
||||||
// TestInvalidOffsets tests error handling for invalid offsets in encoded data
|
// TestInvalidOffsets tests error handling for invalid offsets in encoded data
|
||||||
func TestInvalidOffsets(t *testing.T) {
|
func TestInvalidOffsets(t *testing.T) {
|
||||||
h := makeTrinodeHistory()
|
h := makeTrienodeHistory()
|
||||||
header, keySection, valueSection, _ := h.encode()
|
header, keySection, valueSection, _ := h.encode()
|
||||||
|
|
||||||
// Corrupt key offset in header (make it larger than key section)
|
// Corrupt key offset in header (make it larger than key section)
|
||||||
|
|
@ -395,7 +408,7 @@ func TestInvalidOffsets(t *testing.T) {
|
||||||
// TestTrienodeHistoryReaderNonExistentPath tests reading non-existent paths
|
// TestTrienodeHistoryReaderNonExistentPath tests reading non-existent paths
|
||||||
func TestTrienodeHistoryReaderNonExistentPath(t *testing.T) {
|
func TestTrienodeHistoryReaderNonExistentPath(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
h = makeTrinodeHistory()
|
h = makeTrienodeHistory()
|
||||||
freezer, _ = rawdb.NewTrienodeFreezer(t.TempDir(), false, false)
|
freezer, _ = rawdb.NewTrienodeFreezer(t.TempDir(), false, false)
|
||||||
)
|
)
|
||||||
defer freezer.Close()
|
defer freezer.Close()
|
||||||
|
|
@ -523,7 +536,7 @@ func TestTrienodeHistoryReaderNilKey(t *testing.T) {
|
||||||
|
|
||||||
// TestTrienodeHistoryReaderIterator tests the iterator functionality
|
// TestTrienodeHistoryReaderIterator tests the iterator functionality
|
||||||
func TestTrienodeHistoryReaderIterator(t *testing.T) {
|
func TestTrienodeHistoryReaderIterator(t *testing.T) {
|
||||||
h := makeTrinodeHistory()
|
h := makeTrienodeHistory()
|
||||||
|
|
||||||
// Count expected entries
|
// Count expected entries
|
||||||
expectedCount := 0
|
expectedCount := 0
|
||||||
|
|
@ -614,7 +627,7 @@ func TestSharedLen(t *testing.T) {
|
||||||
// TestDecodeHeaderCorruptedData tests decodeHeader with corrupted data
|
// TestDecodeHeaderCorruptedData tests decodeHeader with corrupted data
|
||||||
func TestDecodeHeaderCorruptedData(t *testing.T) {
|
func TestDecodeHeaderCorruptedData(t *testing.T) {
|
||||||
// Create valid header data first
|
// Create valid header data first
|
||||||
h := makeTrinodeHistory()
|
h := makeTrienodeHistory()
|
||||||
header, _, _, _ := h.encode()
|
header, _, _, _ := h.encode()
|
||||||
|
|
||||||
// Test with empty header
|
// Test with empty header
|
||||||
|
|
@ -661,7 +674,7 @@ func TestDecodeHeaderCorruptedData(t *testing.T) {
|
||||||
|
|
||||||
// TestDecodeSingleCorruptedData tests decodeSingle with corrupted data
|
// TestDecodeSingleCorruptedData tests decodeSingle with corrupted data
|
||||||
func TestDecodeSingleCorruptedData(t *testing.T) {
|
func TestDecodeSingleCorruptedData(t *testing.T) {
|
||||||
h := makeTrinodeHistory()
|
h := makeTrienodeHistory()
|
||||||
_, keySection, _, _ := h.encode()
|
_, keySection, _, _ := h.encode()
|
||||||
|
|
||||||
// Test with empty key section
|
// Test with empty key section
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue