@@ -27,7 +27,7 @@ import (
2727 "github.com/CortexFoundation/CortexTheseus/rlp"
2828)
2929
30- // hasherPool holds LegacyKeccak256 hashers for rlpHash.
30+ // hasherPool holds LegacyKeccak256 buffer for rlpHash.
3131var hasherPool = sync.Pool {
3232 New : func () interface {} { return crypto .NewKeccakState () },
3333}
@@ -75,10 +75,66 @@ func prefixedRlpHash(prefix byte, x interface{}) (h common.Hash) {
7575 return h
7676}
7777
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.
8181 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.
8389 Hash () common.Hash
8490}
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