@@ -47,13 +47,26 @@ var (
4747)
4848
4949func GetBinaryTreeKey (addr common.Address , key []byte ) []byte {
50+ return getBinaryTreeKey (addr , key , false )
51+ }
52+
53+ func getBinaryTreeKey (addr common.Address , offset []byte , overflow bool ) []byte {
5054 hasher := sha256 .New ()
5155 hasher .Write (zeroHash [:12 ])
5256 hasher .Write (addr [:])
53- hasher .Write (key [:31 ])
54- hasher .Write ([]byte {0 })
57+ var buf [32 ]byte
58+ // key is big endian, hashed value is little endian
59+ for i := range offset [:31 ] {
60+ buf [i ] = offset [30 - i ]
61+ }
62+ if overflow {
63+ // Overflow detected when adding MAIN_STORAGE_OFFSET,
64+ // reporting it in the shifter 32 byte value.
65+ buf [31 ] = 1
66+ }
67+ hasher .Write (buf [:])
5568 k := hasher .Sum (nil )
56- k [31 ] = key [31 ]
69+ k [31 ] = offset [31 ]
5770 return k
5871}
5972
@@ -69,24 +82,29 @@ func GetBinaryTreeKeyCodeHash(addr common.Address) []byte {
6982 return GetBinaryTreeKey (addr , k [:])
7083}
7184
72- func GetBinaryTreeKeyStorageSlot (address common.Address , key []byte ) []byte {
73- var k [32 ]byte
85+ func GetBinaryTreeKeyStorageSlot (address common.Address , slotnum []byte ) []byte {
86+ var offset [32 ]byte
7487
7588 // Case when the key belongs to the account header
76- if bytes .Equal (key [:31 ], zeroHash [:31 ]) && key [31 ] < 64 {
77- k [31 ] = 64 + key [31 ]
78- return GetBinaryTreeKey (address , k [:])
89+ if bytes .Equal (slotnum [:31 ], zeroHash [:31 ]) && slotnum [31 ] < 64 {
90+ offset [31 ] = 64 + slotnum [31 ]
91+ return GetBinaryTreeKey (address , offset [:])
7992 }
8093
81- // Set the main storage offset
82- // note that the first 64 bytes of the main offset storage
83- // are unreachable, which is consistent with the spec and
84- // what verkle does.
85- k [0 ] = 1 // 1 << 248
86- copy (k [1 :], key [:31 ])
87- k [31 ] = key [31 ]
88-
89- return GetBinaryTreeKey (address , k [:])
94+ // Set the main storage offset offset = MAIN_STORAGE_OFFSET + slotnum
95+ // * Note that MAIN_STORAGE_OFFSET is 1 << 248, so the number
96+ // can overflow into a 33rd byte, but since the value is
97+ // shifted by one byte in getBinaryTreeKey, this only takes
98+ // note of the overflow, and the value will be added after
99+ // the shift, in order to avoid allocating an extra byte.
100+ // * Note that the first 64 bytes of the main offset storage
101+ // are unreachable, which is consistent with the spec.
102+ // * Note that `slotnum` is big-endian
103+ overflow := slotnum [0 ] == 255
104+ copy (offset [:], slotnum )
105+ offset [0 ] += 1 // 1 << 248, handle overflow out of band
106+
107+ return getBinaryTreeKey (address , offset [:], overflow )
90108}
91109
92110func GetBinaryTreeKeyCodeChunk (address common.Address , chunknr * uint256.Int ) []byte {
0 commit comments