mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-22 04:36:42 +00:00
triedb: address comments from guillaume
This commit is contained in:
parent
8cd4b1736c
commit
f9f67599d2
2 changed files with 27 additions and 10 deletions
|
|
@ -436,11 +436,11 @@ func (s *nodeSetWithOrigin) decode(r *rlp.Stream) error {
|
||||||
// ┌──── Bits (from MSB to LSB) ───┐
|
// ┌──── Bits (from MSB to LSB) ───┐
|
||||||
// │ 7 │ 6 │ 5 │ 4 │ 3 │ 2 │ 1 │ 0 │
|
// │ 7 │ 6 │ 5 │ 4 │ 3 │ 2 │ 1 │ 0 │
|
||||||
// └───────────────────────────────┘
|
// └───────────────────────────────┘
|
||||||
// │ │ │ │ │ │ │ └─ FlagA: marks if value is encoded in compressed format (1 always)
|
// │ │ │ │ │ │ │ └─ FlagA: set if value is encoded in compressed format
|
||||||
// │ │ │ │ │ │ └───── FlagB: marks if no extended bitmap used after the metadata byte
|
// │ │ │ │ │ │ └───── FlagB: set if no extended bitmap is present after the metadata byte
|
||||||
// │ │ │ │ │ └───────── FlagC: bitmap for node (only used when flagB == 1)
|
// │ │ │ │ │ └───────── FlagC: bitmap for node (only used when flagB == 1)
|
||||||
// │ │ │ │ └───────────── FlagD: bitmap for node (only used when flagB == 1)
|
// │ │ │ │ └───────────── FlagD: bitmap for node (only used when flagB == 1)
|
||||||
// │ │ │ └───────────────── FlagE: reserved
|
// │ │ │ └───────────────── FlagE: reserved (marks the presence of the 16th child in a full node)
|
||||||
// │ │ └───────────────────── FlagF: reserved
|
// │ │ └───────────────────── FlagF: reserved
|
||||||
// │ └───────────────────────── FlagG: reserved
|
// │ └───────────────────────── FlagG: reserved
|
||||||
// └───────────────────────────── FlagH: reserved
|
// └───────────────────────────── FlagH: reserved
|
||||||
|
|
@ -468,14 +468,24 @@ func (s *nodeSetWithOrigin) decode(r *rlp.Stream) error {
|
||||||
func encodeNodeCompressed(addExtension bool, elements [][]byte, indices []int) []byte {
|
func encodeNodeCompressed(addExtension bool, elements [][]byte, indices []int) []byte {
|
||||||
var (
|
var (
|
||||||
enc []byte
|
enc []byte
|
||||||
flag = byte(1) // flagA
|
flag = byte(1) // The compression format indicator
|
||||||
)
|
)
|
||||||
|
// Pre-allocate the byte slice for the node encoder
|
||||||
|
size := 1
|
||||||
|
if addExtension {
|
||||||
|
size += 2
|
||||||
|
}
|
||||||
|
for _, element := range elements {
|
||||||
|
size += len(element) + 1
|
||||||
|
}
|
||||||
|
enc = make([]byte, 0, size)
|
||||||
|
|
||||||
if !addExtension {
|
if !addExtension {
|
||||||
flag |= 2 // flagB
|
flag |= 2 // The embedded bitmap indicator
|
||||||
|
|
||||||
// Embedded bitmap
|
// Embedded bitmap
|
||||||
for _, pos := range indices {
|
for _, pos := range indices {
|
||||||
flag |= 1 << (pos + 2) // flagC and flagD
|
flag |= 1 << (pos + 2)
|
||||||
}
|
}
|
||||||
enc = append(enc, flag)
|
enc = append(enc, flag)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -483,9 +493,12 @@ func encodeNodeCompressed(addExtension bool, elements [][]byte, indices []int) [
|
||||||
bitmap := make([]byte, 2) // bitmaps for at most 16 children
|
bitmap := make([]byte, 2) // bitmaps for at most 16 children
|
||||||
for _, pos := range indices {
|
for _, pos := range indices {
|
||||||
// Children[16] is only theoretically possible in the Merkle-Patricia-trie,
|
// Children[16] is only theoretically possible in the Merkle-Patricia-trie,
|
||||||
// in practice this field is never used in the Ethereum case.
|
// in practice this field is never used in the Ethereum case. If it occurs,
|
||||||
|
// use the FlagE for marking the presence.
|
||||||
if pos >= 16 {
|
if pos >= 16 {
|
||||||
panic(fmt.Sprintf("Unexpected node children index %d", pos))
|
log.Warn("Unexpected 16th child encountered in a full node")
|
||||||
|
flag |= 1 << 4 // Use the reserved flagE
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
bitIndex := uint(pos % 8)
|
bitIndex := uint(pos % 8)
|
||||||
bitmap[pos/8] |= 1 << bitIndex
|
bitmap[pos/8] |= 1 << bitIndex
|
||||||
|
|
@ -523,7 +536,7 @@ func decodeNodeCompressed(data []byte) ([][]byte, []int, error) {
|
||||||
if flag&byte(1) == 0 {
|
if flag&byte(1) == 0 {
|
||||||
return nil, nil, errors.New("invalid data: full node value")
|
return nil, nil, errors.New("invalid data: full node value")
|
||||||
}
|
}
|
||||||
noExtend := flag&byte(2) != 0 // flagB
|
noExtend := flag&byte(2) != 0
|
||||||
|
|
||||||
// Reconstruct indices from bitmap
|
// Reconstruct indices from bitmap
|
||||||
var indices []int
|
var indices []int
|
||||||
|
|
@ -548,6 +561,10 @@ func decodeNodeCompressed(data []byte) ([][]byte, []int, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if flag&byte(16) != 0 { // flagE
|
||||||
|
indices = append(indices, 16)
|
||||||
|
log.Info("Unexpected 16th child encountered in a full node")
|
||||||
|
}
|
||||||
data = data[3:]
|
data = data[3:]
|
||||||
}
|
}
|
||||||
// Reconstruct elements
|
// Reconstruct elements
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ func TestEncodeFullNodeCompressed(t *testing.T) {
|
||||||
elements [][]byte
|
elements [][]byte
|
||||||
indices []int
|
indices []int
|
||||||
)
|
)
|
||||||
for i := 0; i < 16; i++ {
|
for i := 0; i <= 16; i++ {
|
||||||
if rand.Intn(2) == 0 {
|
if rand.Intn(2) == 0 {
|
||||||
elements = append(elements, testrand.Bytes(20))
|
elements = append(elements, testrand.Bytes(20))
|
||||||
indices = append(indices, i)
|
indices = append(indices, i)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue