@@ -27,7 +27,7 @@ import (
27
27
"github.com/CortexFoundation/CortexTheseus/rlp"
28
28
)
29
29
30
- // hasherPool holds LegacyKeccak256 hashers for rlpHash.
30
+ // hasherPool holds LegacyKeccak256 buffer for rlpHash.
31
31
var hasherPool = sync.Pool {
32
32
New : func () interface {} { return crypto .NewKeccakState () },
33
33
}
@@ -75,10 +75,66 @@ func prefixedRlpHash(prefix byte, x interface{}) (h common.Hash) {
75
75
return h
76
76
}
77
77
78
- // TrieHasher is the tool used to calculate the hash of derivable list.
79
- // This is internal, do not use.
80
- type TrieHasher interface {
78
+ // ListHasher defines the interface for computing the hash of a derivable list.
79
+ type ListHasher interface {
80
+ // Reset clears the internal state of the hasher, preparing it for reuse.
81
81
Reset ()
82
- Update ([]byte , []byte ) error
82
+
83
+ // Update inserts the given key-value pair into the hasher.
84
+ // The implementation must copy the provided slices, allowing the caller
85
+ // to safely modify them after the call returns.
86
+ Update (key []byte , value []byte ) error
87
+
88
+ // Hash computes and returns the final hash of all inserted key-value pairs.
83
89
Hash () common.Hash
84
90
}
91
+
92
+ // DerivableList is the input to DeriveSha.
93
+ // It is implemented by the 'Transactions' and 'Receipts' types.
94
+ // This is internal, do not use these methods.
95
+ type DerivableList interface {
96
+ Len () int
97
+ EncodeIndex (int , * bytes.Buffer )
98
+ }
99
+
100
+ // encodeForDerive encodes the element in the list at the position i into the buffer.
101
+ func encodeForDerive (list DerivableList , i int , buf * bytes.Buffer ) []byte {
102
+ buf .Reset ()
103
+ list .EncodeIndex (i , buf )
104
+ return buf .Bytes ()
105
+ }
106
+
107
+ // DeriveSha creates the tree hashes of transactions, receipts, and withdrawals in a block header.
108
+ func DeriveSha (list DerivableList , hasher ListHasher ) common.Hash {
109
+ hasher .Reset ()
110
+
111
+ // Allocate a buffer for value encoding. As the hasher is claimed that all
112
+ // supplied key value pairs will be copied by hasher and safe to reuse the
113
+ // encoding buffer.
114
+ valueBuf := encodeBufferPool .Get ().(* bytes.Buffer )
115
+ defer encodeBufferPool .Put (valueBuf )
116
+
117
+ // StackTrie requires values to be inserted in increasing hash order, which is not the
118
+ // order that `list` provides hashes in. This insertion sequence ensures that the
119
+ // order is correct.
120
+ //
121
+ // The error returned by hasher is omitted because hasher will produce an incorrect
122
+ // hash in case any error occurs.
123
+ var indexBuf []byte
124
+ for i := 1 ; i < list .Len () && i <= 0x7f ; i ++ {
125
+ indexBuf = rlp .AppendUint64 (indexBuf [:0 ], uint64 (i ))
126
+ value := encodeForDerive (list , i , valueBuf )
127
+ hasher .Update (indexBuf , value )
128
+ }
129
+ if list .Len () > 0 {
130
+ indexBuf = rlp .AppendUint64 (indexBuf [:0 ], 0 )
131
+ value := encodeForDerive (list , 0 , valueBuf )
132
+ hasher .Update (indexBuf , value )
133
+ }
134
+ for i := 0x80 ; i < list .Len (); i ++ {
135
+ indexBuf = rlp .AppendUint64 (indexBuf [:0 ], uint64 (i ))
136
+ value := encodeForDerive (list , i , valueBuf )
137
+ hasher .Update (indexBuf , value )
138
+ }
139
+ return hasher .Hash ()
140
+ }
0 commit comments