github.com/ledgerwatch/erigon-lib@v1.0.0/commitment/hex_patricia_hashed.go (about)

     1  /*
     2     Copyright 2022 The Erigon contributors
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package commitment
    18  
    19  import (
    20  	"bytes"
    21  	"encoding/binary"
    22  	"encoding/hex"
    23  	"fmt"
    24  	"hash"
    25  	"io"
    26  	"math/bits"
    27  	"strings"
    28  
    29  	"github.com/holiman/uint256"
    30  	"github.com/ledgerwatch/log/v3"
    31  	"golang.org/x/crypto/sha3"
    32  
    33  	"github.com/ledgerwatch/erigon-lib/common"
    34  	"github.com/ledgerwatch/erigon-lib/common/length"
    35  	"github.com/ledgerwatch/erigon-lib/rlp"
    36  )
    37  
    38  // keccakState wraps sha3.state. In addition to the usual hash methods, it also supports
    39  // Read to get a variable amount of data from the hash state. Read is faster than Sum
    40  // because it doesn't copy the internal state, but also modifies the internal state.
    41  type keccakState interface {
    42  	hash.Hash
    43  	Read([]byte) (int, error)
    44  }
    45  
    46  // HexPatriciaHashed implements commitment based on patricia merkle tree with radix 16,
    47  // with keys pre-hashed by keccak256
    48  type HexPatriciaHashed struct {
    49  	root Cell // Root cell of the tree
    50  	// How many rows (starting from row 0) are currently active and have corresponding selected columns
    51  	// Last active row does not have selected column
    52  	activeRows int
    53  	// Length of the key that reflects current positioning of the grid. It maybe larger than number of active rows,
    54  	// if an account leaf cell represents multiple nibbles in the key
    55  	currentKeyLen int
    56  	accountKeyLen int
    57  	// Rows of the grid correspond to the level of depth in the patricia tree
    58  	// Columns of the grid correspond to pointers to the nodes further from the root
    59  	grid         [128][16]Cell // First 64 rows of this grid are for account trie, and next 64 rows are for storage trie
    60  	currentKey   [128]byte     // For each row indicates which column is currently selected
    61  	depths       [128]int      // For each row, the depth of cells in that row
    62  	branchBefore [128]bool     // For each row, whether there was a branch node in the database loaded in unfold
    63  	touchMap     [128]uint16   // For each row, bitmap of cells that were either present before modification, or modified or deleted
    64  	afterMap     [128]uint16   // For each row, bitmap of cells that were present after modification
    65  	keccak       keccakState
    66  	keccak2      keccakState
    67  	rootChecked  bool // Set to false if it is not known whether the root is empty, set to true if it is checked
    68  	rootTouched  bool
    69  	rootPresent  bool
    70  	trace        bool
    71  	// Function used to load branch node and fill up the cells
    72  	// For each cell, it sets the cell type, clears the modified flag, fills the hash,
    73  	// and for the extension, account, and leaf type, the `l` and `k`
    74  	branchFn func(prefix []byte) ([]byte, error)
    75  	// Function used to fetch account with given plain key
    76  	accountFn func(plainKey []byte, cell *Cell) error
    77  	// Function used to fetch storage with given plain key
    78  	storageFn func(plainKey []byte, cell *Cell) error
    79  
    80  	hashAuxBuffer [128]byte     // buffer to compute cell hash or write hash-related things
    81  	auxBuffer     *bytes.Buffer // auxiliary buffer used during branch updates encoding
    82  }
    83  
    84  // represents state of the tree
    85  type state struct {
    86  	Root          []byte      // encoded root cell
    87  	Depths        [128]int    // For each row, the depth of cells in that row
    88  	TouchMap      [128]uint16 // For each row, bitmap of cells that were either present before modification, or modified or deleted
    89  	AfterMap      [128]uint16 // For each row, bitmap of cells that were present after modification
    90  	BranchBefore  [128]bool   // For each row, whether there was a branch node in the database loaded in unfold
    91  	CurrentKey    [128]byte   // For each row indicates which column is currently selected
    92  	CurrentKeyLen int8
    93  	RootChecked   bool // Set to false if it is not known whether the root is empty, set to true if it is checked
    94  	RootTouched   bool
    95  	RootPresent   bool
    96  }
    97  
    98  func NewHexPatriciaHashed(accountKeyLen int,
    99  	branchFn func(prefix []byte) ([]byte, error),
   100  	accountFn func(plainKey []byte, cell *Cell) error,
   101  	storageFn func(plainKey []byte, cell *Cell) error,
   102  ) *HexPatriciaHashed {
   103  	return &HexPatriciaHashed{
   104  		keccak:        sha3.NewLegacyKeccak256().(keccakState),
   105  		keccak2:       sha3.NewLegacyKeccak256().(keccakState),
   106  		accountKeyLen: accountKeyLen,
   107  		branchFn:      branchFn,
   108  		accountFn:     accountFn,
   109  		storageFn:     storageFn,
   110  		auxBuffer:     bytes.NewBuffer(make([]byte, 8192)),
   111  	}
   112  }
   113  
   114  type Cell struct {
   115  	Balance       uint256.Int
   116  	Nonce         uint64
   117  	hl            int // Length of the hash (or embedded)
   118  	StorageLen    int
   119  	apl           int // length of account plain key
   120  	spl           int // length of the storage plain key
   121  	downHashedLen int
   122  	extLen        int
   123  	downHashedKey [128]byte
   124  	extension     [64]byte
   125  	spk           [length.Addr + length.Hash]byte // storage plain key
   126  	h             [length.Hash]byte               // cell hash
   127  	CodeHash      [length.Hash]byte               // hash of the bytecode
   128  	Storage       [length.Hash]byte
   129  	apk           [length.Addr]byte // account plain key
   130  	Delete        bool
   131  }
   132  
   133  var (
   134  	EmptyRootHash, _ = hex.DecodeString("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
   135  	EmptyCodeHash, _ = hex.DecodeString("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")
   136  )
   137  
   138  func (cell *Cell) fillEmpty() {
   139  	cell.apl = 0
   140  	cell.spl = 0
   141  	cell.downHashedLen = 0
   142  	cell.extLen = 0
   143  	cell.hl = 0
   144  	cell.Nonce = 0
   145  	cell.Balance.Clear()
   146  	copy(cell.CodeHash[:], EmptyCodeHash)
   147  	cell.StorageLen = 0
   148  	cell.Delete = false
   149  }
   150  
   151  func (cell *Cell) fillFromUpperCell(upCell *Cell, depth, depthIncrement int) {
   152  	if upCell.downHashedLen >= depthIncrement {
   153  		cell.downHashedLen = upCell.downHashedLen - depthIncrement
   154  	} else {
   155  		cell.downHashedLen = 0
   156  	}
   157  	if upCell.downHashedLen > depthIncrement {
   158  		copy(cell.downHashedKey[:], upCell.downHashedKey[depthIncrement:upCell.downHashedLen])
   159  	}
   160  	if upCell.extLen >= depthIncrement {
   161  		cell.extLen = upCell.extLen - depthIncrement
   162  	} else {
   163  		cell.extLen = 0
   164  	}
   165  	if upCell.extLen > depthIncrement {
   166  		copy(cell.extension[:], upCell.extension[depthIncrement:upCell.extLen])
   167  	}
   168  	if depth <= 64 {
   169  		cell.apl = upCell.apl
   170  		if upCell.apl > 0 {
   171  			copy(cell.apk[:], upCell.apk[:cell.apl])
   172  			cell.Balance.Set(&upCell.Balance)
   173  			cell.Nonce = upCell.Nonce
   174  			copy(cell.CodeHash[:], upCell.CodeHash[:])
   175  			cell.extLen = upCell.extLen
   176  			if upCell.extLen > 0 {
   177  				copy(cell.extension[:], upCell.extension[:upCell.extLen])
   178  			}
   179  		}
   180  	} else {
   181  		cell.apl = 0
   182  	}
   183  	cell.spl = upCell.spl
   184  	if upCell.spl > 0 {
   185  		copy(cell.spk[:], upCell.spk[:upCell.spl])
   186  		cell.StorageLen = upCell.StorageLen
   187  		if upCell.StorageLen > 0 {
   188  			copy(cell.Storage[:], upCell.Storage[:upCell.StorageLen])
   189  		}
   190  	}
   191  	cell.hl = upCell.hl
   192  	if upCell.hl > 0 {
   193  		copy(cell.h[:], upCell.h[:upCell.hl])
   194  	}
   195  }
   196  
   197  func (cell *Cell) fillFromLowerCell(lowCell *Cell, lowDepth int, preExtension []byte, nibble int) {
   198  	if lowCell.apl > 0 || lowDepth < 64 {
   199  		cell.apl = lowCell.apl
   200  	}
   201  	if lowCell.apl > 0 {
   202  		copy(cell.apk[:], lowCell.apk[:cell.apl])
   203  		cell.Balance.Set(&lowCell.Balance)
   204  		cell.Nonce = lowCell.Nonce
   205  		copy(cell.CodeHash[:], lowCell.CodeHash[:])
   206  	}
   207  	cell.spl = lowCell.spl
   208  	if lowCell.spl > 0 {
   209  		copy(cell.spk[:], lowCell.spk[:cell.spl])
   210  		cell.StorageLen = lowCell.StorageLen
   211  		if lowCell.StorageLen > 0 {
   212  			copy(cell.Storage[:], lowCell.Storage[:lowCell.StorageLen])
   213  		}
   214  	}
   215  	if lowCell.hl > 0 {
   216  		if (lowCell.apl == 0 && lowDepth < 64) || (lowCell.spl == 0 && lowDepth > 64) {
   217  			// Extension is related to either accounts branch node, or storage branch node, we prepend it by preExtension | nibble
   218  			if len(preExtension) > 0 {
   219  				copy(cell.extension[:], preExtension)
   220  			}
   221  			cell.extension[len(preExtension)] = byte(nibble)
   222  			if lowCell.extLen > 0 {
   223  				copy(cell.extension[1+len(preExtension):], lowCell.extension[:lowCell.extLen])
   224  			}
   225  			cell.extLen = lowCell.extLen + 1 + len(preExtension)
   226  		} else {
   227  			// Extension is related to a storage branch node, so we copy it upwards as is
   228  			cell.extLen = lowCell.extLen
   229  			if lowCell.extLen > 0 {
   230  				copy(cell.extension[:], lowCell.extension[:lowCell.extLen])
   231  			}
   232  		}
   233  	}
   234  	cell.hl = lowCell.hl
   235  	if lowCell.hl > 0 {
   236  		copy(cell.h[:], lowCell.h[:lowCell.hl])
   237  	}
   238  }
   239  
   240  func hashKey(keccak keccakState, plainKey []byte, dest []byte, hashedKeyOffset int) error {
   241  	keccak.Reset()
   242  	var hashBufBack [length.Hash]byte
   243  	hashBuf := hashBufBack[:]
   244  	if _, err := keccak.Write(plainKey); err != nil {
   245  		return err
   246  	}
   247  	if _, err := keccak.Read(hashBuf); err != nil {
   248  		return err
   249  	}
   250  	hashBuf = hashBuf[hashedKeyOffset/2:]
   251  	var k int
   252  	if hashedKeyOffset%2 == 1 {
   253  		dest[0] = hashBuf[0] & 0xf
   254  		k++
   255  		hashBuf = hashBuf[1:]
   256  	}
   257  	for _, c := range hashBuf {
   258  		dest[k] = (c >> 4) & 0xf
   259  		k++
   260  		dest[k] = c & 0xf
   261  		k++
   262  	}
   263  	return nil
   264  }
   265  
   266  func (cell *Cell) deriveHashedKeys(depth int, keccak keccakState, accountKeyLen int) error {
   267  	extraLen := 0
   268  	if cell.apl > 0 {
   269  		if depth > 64 {
   270  			return fmt.Errorf("deriveHashedKeys accountPlainKey present at depth > 64")
   271  		}
   272  		extraLen = 64 - depth
   273  	}
   274  	if cell.spl > 0 {
   275  		if depth >= 64 {
   276  			extraLen = 128 - depth
   277  		} else {
   278  			extraLen += 64
   279  		}
   280  	}
   281  	if extraLen > 0 {
   282  		if cell.downHashedLen > 0 {
   283  			copy(cell.downHashedKey[extraLen:], cell.downHashedKey[:cell.downHashedLen])
   284  		}
   285  		cell.downHashedLen += extraLen
   286  		var hashedKeyOffset, downOffset int
   287  		if cell.apl > 0 {
   288  			if err := hashKey(keccak, cell.apk[:cell.apl], cell.downHashedKey[:], depth); err != nil {
   289  				return err
   290  			}
   291  			downOffset = 64 - depth
   292  		}
   293  		if cell.spl > 0 {
   294  			if depth >= 64 {
   295  				hashedKeyOffset = depth - 64
   296  			}
   297  			if err := hashKey(keccak, cell.spk[accountKeyLen:cell.spl], cell.downHashedKey[downOffset:], hashedKeyOffset); err != nil {
   298  				return err
   299  			}
   300  		}
   301  	}
   302  	return nil
   303  }
   304  
   305  func (cell *Cell) fillFromFields(data []byte, pos int, fieldBits PartFlags) (int, error) {
   306  	if fieldBits&HashedKeyPart != 0 {
   307  		l, n := binary.Uvarint(data[pos:])
   308  		if n == 0 {
   309  			return 0, fmt.Errorf("fillFromFields buffer too small for hashedKey len")
   310  		} else if n < 0 {
   311  			return 0, fmt.Errorf("fillFromFields value overflow for hashedKey len")
   312  		}
   313  		pos += n
   314  		if len(data) < pos+int(l) {
   315  			return 0, fmt.Errorf("fillFromFields buffer too small for hashedKey exp %d got %d", pos+int(l), len(data))
   316  		}
   317  		cell.downHashedLen = int(l)
   318  		cell.extLen = int(l)
   319  		if l > 0 {
   320  			copy(cell.downHashedKey[:], data[pos:pos+int(l)])
   321  			copy(cell.extension[:], data[pos:pos+int(l)])
   322  			pos += int(l)
   323  		}
   324  	} else {
   325  		cell.downHashedLen = 0
   326  		cell.extLen = 0
   327  	}
   328  	if fieldBits&AccountPlainPart != 0 {
   329  		l, n := binary.Uvarint(data[pos:])
   330  		if n == 0 {
   331  			return 0, fmt.Errorf("fillFromFields buffer too small for accountPlainKey len")
   332  		} else if n < 0 {
   333  			return 0, fmt.Errorf("fillFromFields value overflow for accountPlainKey len")
   334  		}
   335  		pos += n
   336  		if len(data) < pos+int(l) {
   337  			return 0, fmt.Errorf("fillFromFields buffer too small for accountPlainKey")
   338  		}
   339  		cell.apl = int(l)
   340  		if l > 0 {
   341  			copy(cell.apk[:], data[pos:pos+int(l)])
   342  			pos += int(l)
   343  		}
   344  	} else {
   345  		cell.apl = 0
   346  	}
   347  	if fieldBits&StoragePlainPart != 0 {
   348  		l, n := binary.Uvarint(data[pos:])
   349  		if n == 0 {
   350  			return 0, fmt.Errorf("fillFromFields buffer too small for storagePlainKey len")
   351  		} else if n < 0 {
   352  			return 0, fmt.Errorf("fillFromFields value overflow for storagePlainKey len")
   353  		}
   354  		pos += n
   355  		if len(data) < pos+int(l) {
   356  			return 0, fmt.Errorf("fillFromFields buffer too small for storagePlainKey")
   357  		}
   358  		cell.spl = int(l)
   359  		if l > 0 {
   360  			copy(cell.spk[:], data[pos:pos+int(l)])
   361  			pos += int(l)
   362  		}
   363  	} else {
   364  		cell.spl = 0
   365  	}
   366  	if fieldBits&HashPart != 0 {
   367  		l, n := binary.Uvarint(data[pos:])
   368  		if n == 0 {
   369  			return 0, fmt.Errorf("fillFromFields buffer too small for hash len")
   370  		} else if n < 0 {
   371  			return 0, fmt.Errorf("fillFromFields value overflow for hash len")
   372  		}
   373  		pos += n
   374  		if len(data) < pos+int(l) {
   375  			return 0, fmt.Errorf("fillFromFields buffer too small for hash")
   376  		}
   377  		cell.hl = int(l)
   378  		if l > 0 {
   379  			copy(cell.h[:], data[pos:pos+int(l)])
   380  			pos += int(l)
   381  		}
   382  	} else {
   383  		cell.hl = 0
   384  	}
   385  	return pos, nil
   386  }
   387  
   388  func (cell *Cell) setStorage(value []byte) {
   389  	cell.StorageLen = len(value)
   390  	if len(value) > 0 {
   391  		copy(cell.Storage[:], value)
   392  	}
   393  }
   394  
   395  func (cell *Cell) setAccountFields(codeHash []byte, balance *uint256.Int, nonce uint64) {
   396  	copy(cell.CodeHash[:], codeHash)
   397  
   398  	cell.Balance.SetBytes(balance.Bytes())
   399  	cell.Nonce = nonce
   400  }
   401  
   402  func (cell *Cell) accountForHashing(buffer []byte, storageRootHash [length.Hash]byte) int {
   403  	balanceBytes := 0
   404  	if !cell.Balance.LtUint64(128) {
   405  		balanceBytes = cell.Balance.ByteLen()
   406  	}
   407  
   408  	var nonceBytes int
   409  	if cell.Nonce < 128 && cell.Nonce != 0 {
   410  		nonceBytes = 0
   411  	} else {
   412  		nonceBytes = common.BitLenToByteLen(bits.Len64(cell.Nonce))
   413  	}
   414  
   415  	var structLength = uint(balanceBytes + nonceBytes + 2)
   416  	structLength += 66 // Two 32-byte arrays + 2 prefixes
   417  
   418  	var pos int
   419  	if structLength < 56 {
   420  		buffer[0] = byte(192 + structLength)
   421  		pos = 1
   422  	} else {
   423  		lengthBytes := common.BitLenToByteLen(bits.Len(structLength))
   424  		buffer[0] = byte(247 + lengthBytes)
   425  
   426  		for i := lengthBytes; i > 0; i-- {
   427  			buffer[i] = byte(structLength)
   428  			structLength >>= 8
   429  		}
   430  
   431  		pos = lengthBytes + 1
   432  	}
   433  
   434  	// Encoding nonce
   435  	if cell.Nonce < 128 && cell.Nonce != 0 {
   436  		buffer[pos] = byte(cell.Nonce)
   437  	} else {
   438  		buffer[pos] = byte(128 + nonceBytes)
   439  		var nonce = cell.Nonce
   440  		for i := nonceBytes; i > 0; i-- {
   441  			buffer[pos+i] = byte(nonce)
   442  			nonce >>= 8
   443  		}
   444  	}
   445  	pos += 1 + nonceBytes
   446  
   447  	// Encoding balance
   448  	if cell.Balance.LtUint64(128) && !cell.Balance.IsZero() {
   449  		buffer[pos] = byte(cell.Balance.Uint64())
   450  		pos++
   451  	} else {
   452  		buffer[pos] = byte(128 + balanceBytes)
   453  		pos++
   454  		cell.Balance.WriteToSlice(buffer[pos : pos+balanceBytes])
   455  		pos += balanceBytes
   456  	}
   457  
   458  	// Encoding Root and CodeHash
   459  	buffer[pos] = 128 + 32
   460  	pos++
   461  	copy(buffer[pos:], storageRootHash[:])
   462  	pos += 32
   463  	buffer[pos] = 128 + 32
   464  	pos++
   465  	copy(buffer[pos:], cell.CodeHash[:])
   466  	pos += 32
   467  	return pos
   468  }
   469  
   470  func (hph *HexPatriciaHashed) completeLeafHash(buf, keyPrefix []byte, kp, kl, compactLen int, key []byte, compact0 byte, ni int, val rlp.RlpSerializable, singleton bool) ([]byte, error) {
   471  	totalLen := kp + kl + val.DoubleRLPLen()
   472  	var lenPrefix [4]byte
   473  	pt := rlp.GenerateStructLen(lenPrefix[:], totalLen)
   474  	embedded := !singleton && totalLen+pt < length.Hash
   475  	var writer io.Writer
   476  	if embedded {
   477  		//hph.byteArrayWriter.Setup(buf)
   478  		hph.auxBuffer.Reset()
   479  		writer = hph.auxBuffer
   480  	} else {
   481  		hph.keccak.Reset()
   482  		writer = hph.keccak
   483  	}
   484  	if _, err := writer.Write(lenPrefix[:pt]); err != nil {
   485  		return nil, err
   486  	}
   487  	if _, err := writer.Write(keyPrefix[:kp]); err != nil {
   488  		return nil, err
   489  	}
   490  	var b [1]byte
   491  	b[0] = compact0
   492  	if _, err := writer.Write(b[:]); err != nil {
   493  		return nil, err
   494  	}
   495  	for i := 1; i < compactLen; i++ {
   496  		b[0] = key[ni]*16 + key[ni+1]
   497  		if _, err := writer.Write(b[:]); err != nil {
   498  			return nil, err
   499  		}
   500  		ni += 2
   501  	}
   502  	var prefixBuf [8]byte
   503  	if err := val.ToDoubleRLP(writer, prefixBuf[:]); err != nil {
   504  		return nil, err
   505  	}
   506  	if embedded {
   507  		buf = hph.auxBuffer.Bytes()
   508  	} else {
   509  		var hashBuf [33]byte
   510  		hashBuf[0] = 0x80 + length.Hash
   511  		if _, err := hph.keccak.Read(hashBuf[1:]); err != nil {
   512  			return nil, err
   513  		}
   514  		buf = append(buf, hashBuf[:]...)
   515  	}
   516  	return buf, nil
   517  }
   518  
   519  func (hph *HexPatriciaHashed) leafHashWithKeyVal(buf, key []byte, val rlp.RlpSerializableBytes, singleton bool) ([]byte, error) {
   520  	// Compute the total length of binary representation
   521  	var kp, kl int
   522  	// Write key
   523  	var compactLen int
   524  	var ni int
   525  	var compact0 byte
   526  	compactLen = (len(key)-1)/2 + 1
   527  	if len(key)&1 == 0 {
   528  		compact0 = 0x30 + key[0] // Odd: (3<<4) + first nibble
   529  		ni = 1
   530  	} else {
   531  		compact0 = 0x20
   532  	}
   533  	var keyPrefix [1]byte
   534  	if compactLen > 1 {
   535  		keyPrefix[0] = 0x80 + byte(compactLen)
   536  		kp = 1
   537  		kl = compactLen
   538  	} else {
   539  		kl = 1
   540  	}
   541  	return hph.completeLeafHash(buf, keyPrefix[:], kp, kl, compactLen, key, compact0, ni, val, singleton)
   542  }
   543  
   544  func (hph *HexPatriciaHashed) accountLeafHashWithKey(buf, key []byte, val rlp.RlpSerializable) ([]byte, error) {
   545  	// Compute the total length of binary representation
   546  	var kp, kl int
   547  	// Write key
   548  	var compactLen int
   549  	var ni int
   550  	var compact0 byte
   551  	if hasTerm(key) {
   552  		compactLen = (len(key)-1)/2 + 1
   553  		if len(key)&1 == 0 {
   554  			compact0 = 48 + key[0] // Odd (1<<4) + first nibble
   555  			ni = 1
   556  		} else {
   557  			compact0 = 32
   558  		}
   559  	} else {
   560  		compactLen = len(key)/2 + 1
   561  		if len(key)&1 == 1 {
   562  			compact0 = 16 + key[0] // Odd (1<<4) + first nibble
   563  			ni = 1
   564  		}
   565  	}
   566  	var keyPrefix [1]byte
   567  	if compactLen > 1 {
   568  		keyPrefix[0] = byte(128 + compactLen)
   569  		kp = 1
   570  		kl = compactLen
   571  	} else {
   572  		kl = 1
   573  	}
   574  	return hph.completeLeafHash(buf, keyPrefix[:], kp, kl, compactLen, key, compact0, ni, val, true)
   575  }
   576  
   577  func (hph *HexPatriciaHashed) extensionHash(key []byte, hash []byte) ([length.Hash]byte, error) {
   578  	var hashBuf [length.Hash]byte
   579  
   580  	// Compute the total length of binary representation
   581  	var kp, kl int
   582  	// Write key
   583  	var compactLen int
   584  	var ni int
   585  	var compact0 byte
   586  	if hasTerm(key) {
   587  		compactLen = (len(key)-1)/2 + 1
   588  		if len(key)&1 == 0 {
   589  			compact0 = 0x30 + key[0] // Odd: (3<<4) + first nibble
   590  			ni = 1
   591  		} else {
   592  			compact0 = 0x20
   593  		}
   594  	} else {
   595  		compactLen = len(key)/2 + 1
   596  		if len(key)&1 == 1 {
   597  			compact0 = 0x10 + key[0] // Odd: (1<<4) + first nibble
   598  			ni = 1
   599  		}
   600  	}
   601  	var keyPrefix [1]byte
   602  	if compactLen > 1 {
   603  		keyPrefix[0] = 0x80 + byte(compactLen)
   604  		kp = 1
   605  		kl = compactLen
   606  	} else {
   607  		kl = 1
   608  	}
   609  	totalLen := kp + kl + 33
   610  	var lenPrefix [4]byte
   611  	pt := rlp.GenerateStructLen(lenPrefix[:], totalLen)
   612  	hph.keccak.Reset()
   613  	if _, err := hph.keccak.Write(lenPrefix[:pt]); err != nil {
   614  		return hashBuf, err
   615  	}
   616  	if _, err := hph.keccak.Write(keyPrefix[:kp]); err != nil {
   617  		return hashBuf, err
   618  	}
   619  	var b [1]byte
   620  	b[0] = compact0
   621  	if _, err := hph.keccak.Write(b[:]); err != nil {
   622  		return hashBuf, err
   623  	}
   624  	for i := 1; i < compactLen; i++ {
   625  		b[0] = key[ni]*16 + key[ni+1]
   626  		if _, err := hph.keccak.Write(b[:]); err != nil {
   627  			return hashBuf, err
   628  		}
   629  		ni += 2
   630  	}
   631  	b[0] = 0x80 + length.Hash
   632  	if _, err := hph.keccak.Write(b[:]); err != nil {
   633  		return hashBuf, err
   634  	}
   635  	if _, err := hph.keccak.Write(hash); err != nil {
   636  		return hashBuf, err
   637  	}
   638  	// Replace previous hash with the new one
   639  	if _, err := hph.keccak.Read(hashBuf[:]); err != nil {
   640  		return hashBuf, err
   641  	}
   642  	return hashBuf, nil
   643  }
   644  
   645  func (hph *HexPatriciaHashed) computeCellHashLen(cell *Cell, depth int) int {
   646  	if cell.spl > 0 && depth >= 64 {
   647  		keyLen := 128 - depth + 1 // Length of hex key with terminator character
   648  		var kp, kl int
   649  		compactLen := (keyLen-1)/2 + 1
   650  		if compactLen > 1 {
   651  			kp = 1
   652  			kl = compactLen
   653  		} else {
   654  			kl = 1
   655  		}
   656  		val := rlp.RlpSerializableBytes(cell.Storage[:cell.StorageLen])
   657  		totalLen := kp + kl + val.DoubleRLPLen()
   658  		var lenPrefix [4]byte
   659  		pt := rlp.GenerateStructLen(lenPrefix[:], totalLen)
   660  		if totalLen+pt < length.Hash {
   661  			return totalLen + pt
   662  		}
   663  	}
   664  	return length.Hash + 1
   665  }
   666  
   667  func (hph *HexPatriciaHashed) computeCellHash(cell *Cell, depth int, buf []byte) ([]byte, error) {
   668  	var err error
   669  	var storageRootHash [length.Hash]byte
   670  	storageRootHashIsSet := false
   671  	if cell.spl > 0 {
   672  		var hashedKeyOffset int
   673  		if depth >= 64 {
   674  			hashedKeyOffset = depth - 64
   675  		}
   676  		singleton := depth <= 64
   677  		if err := hashKey(hph.keccak, cell.spk[hph.accountKeyLen:cell.spl], cell.downHashedKey[:], hashedKeyOffset); err != nil {
   678  			return nil, err
   679  		}
   680  		cell.downHashedKey[64-hashedKeyOffset] = 16 // Add terminator
   681  		if singleton {
   682  			if hph.trace {
   683  				fmt.Printf("leafHashWithKeyVal(singleton) for [%x]=>[%x]\n", cell.downHashedKey[:64-hashedKeyOffset+1], cell.Storage[:cell.StorageLen])
   684  			}
   685  			aux := make([]byte, 0, 33)
   686  			if aux, err = hph.leafHashWithKeyVal(aux, cell.downHashedKey[:64-hashedKeyOffset+1], cell.Storage[:cell.StorageLen], true); err != nil {
   687  				return nil, err
   688  			}
   689  			storageRootHash = *(*[length.Hash]byte)(aux[1:])
   690  			storageRootHashIsSet = true
   691  		} else {
   692  			if hph.trace {
   693  				fmt.Printf("leafHashWithKeyVal for [%x]=>[%x]\n", cell.downHashedKey[:64-hashedKeyOffset+1], cell.Storage[:cell.StorageLen])
   694  			}
   695  			return hph.leafHashWithKeyVal(buf, cell.downHashedKey[:64-hashedKeyOffset+1], cell.Storage[:cell.StorageLen], false)
   696  		}
   697  	}
   698  	if cell.apl > 0 {
   699  		if err := hashKey(hph.keccak, cell.apk[:cell.apl], cell.downHashedKey[:], depth); err != nil {
   700  			return nil, err
   701  		}
   702  		cell.downHashedKey[64-depth] = 16 // Add terminator
   703  		if !storageRootHashIsSet {
   704  			if cell.extLen > 0 {
   705  				// Extension
   706  				if cell.hl > 0 {
   707  					if hph.trace {
   708  						fmt.Printf("extensionHash for [%x]=>[%x]\n", cell.extension[:cell.extLen], cell.h[:cell.hl])
   709  					}
   710  					if storageRootHash, err = hph.extensionHash(cell.extension[:cell.extLen], cell.h[:cell.hl]); err != nil {
   711  						return nil, err
   712  					}
   713  				} else {
   714  					return nil, fmt.Errorf("computeCellHash extension without hash")
   715  				}
   716  			} else if cell.hl > 0 {
   717  				storageRootHash = cell.h
   718  			} else {
   719  				storageRootHash = *(*[length.Hash]byte)(EmptyRootHash)
   720  			}
   721  		}
   722  		var valBuf [128]byte
   723  		valLen := cell.accountForHashing(valBuf[:], storageRootHash)
   724  		if hph.trace {
   725  			fmt.Printf("accountLeafHashWithKey for [%x]=>[%x]\n", hph.hashAuxBuffer[:65-depth], valBuf[:valLen])
   726  		}
   727  		return hph.accountLeafHashWithKey(buf, cell.downHashedKey[:65-depth], rlp.RlpEncodedBytes(valBuf[:valLen]))
   728  	}
   729  	buf = append(buf, 0x80+32)
   730  	if cell.extLen > 0 {
   731  		// Extension
   732  		if cell.hl > 0 {
   733  			if hph.trace {
   734  				fmt.Printf("extensionHash for [%x]=>[%x]\n", cell.extension[:cell.extLen], cell.h[:cell.hl])
   735  			}
   736  			var hash [length.Hash]byte
   737  			if hash, err = hph.extensionHash(cell.extension[:cell.extLen], cell.h[:cell.hl]); err != nil {
   738  				return nil, err
   739  			}
   740  			buf = append(buf, hash[:]...)
   741  		} else {
   742  			return nil, fmt.Errorf("computeCellHash extension without hash")
   743  		}
   744  	} else if cell.hl > 0 {
   745  		buf = append(buf, cell.h[:cell.hl]...)
   746  	} else {
   747  		buf = append(buf, EmptyRootHash...)
   748  	}
   749  	return buf, nil
   750  }
   751  
   752  func (hph *HexPatriciaHashed) needUnfolding(hashedKey []byte) int {
   753  	var cell *Cell
   754  	var depth int
   755  	if hph.activeRows == 0 {
   756  		if hph.trace {
   757  			fmt.Printf("needUnfolding root, rootChecked = %t\n", hph.rootChecked)
   758  		}
   759  		if hph.rootChecked && hph.root.downHashedLen == 0 && hph.root.hl == 0 {
   760  			// Previously checked, empty root, no unfolding needed
   761  			return 0
   762  		}
   763  		cell = &hph.root
   764  		if cell.downHashedLen == 0 && cell.hl == 0 && !hph.rootChecked {
   765  			// Need to attempt to unfold the root
   766  			return 1
   767  		}
   768  	} else {
   769  		col := int(hashedKey[hph.currentKeyLen])
   770  		cell = &hph.grid[hph.activeRows-1][col]
   771  		depth = hph.depths[hph.activeRows-1]
   772  		if hph.trace {
   773  			fmt.Printf("needUnfolding cell (%d, %x), currentKey=[%x], depth=%d, cell.h=[%x]\n", hph.activeRows-1, col, hph.currentKey[:hph.currentKeyLen], depth, cell.h[:cell.hl])
   774  		}
   775  	}
   776  	if len(hashedKey) <= depth {
   777  		return 0
   778  	}
   779  	if cell.downHashedLen == 0 {
   780  		if cell.hl == 0 {
   781  			// cell is empty, no need to unfold further
   782  			return 0
   783  		}
   784  		// unfold branch node
   785  		return 1
   786  	}
   787  	cpl := commonPrefixLen(hashedKey[depth:], cell.downHashedKey[:cell.downHashedLen-1])
   788  	if hph.trace {
   789  		fmt.Printf("cpl=%d, cell.downHashedKey=[%x], depth=%d, hashedKey[depth:]=[%x]\n", cpl, cell.downHashedKey[:cell.downHashedLen], depth, hashedKey[depth:])
   790  	}
   791  	unfolding := cpl + 1
   792  	if depth < 64 && depth+unfolding > 64 {
   793  		// This is to make sure that unfolding always breaks at the level where storage subtrees start
   794  		unfolding = 64 - depth
   795  		if hph.trace {
   796  			fmt.Printf("adjusted unfolding=%d\n", unfolding)
   797  		}
   798  	}
   799  	return unfolding
   800  }
   801  
   802  // unfoldBranchNode returns true if unfolding has been done
   803  func (hph *HexPatriciaHashed) unfoldBranchNode(row int, deleted bool, depth int) (bool, error) {
   804  	branchData, err := hph.branchFn(hexToCompact(hph.currentKey[:hph.currentKeyLen]))
   805  	if err != nil {
   806  		return false, err
   807  	}
   808  	if !hph.rootChecked && hph.currentKeyLen == 0 && len(branchData) == 0 {
   809  		// Special case - empty or deleted root
   810  		hph.rootChecked = true
   811  		return false, nil
   812  	}
   813  	if len(branchData) == 0 {
   814  		log.Warn("got empty branch data during unfold", "key", hex.EncodeToString(hexToCompact(hph.currentKey[:hph.currentKeyLen])), "row", row, "depth", depth, "deleted", deleted)
   815  	}
   816  	hph.branchBefore[row] = true
   817  	bitmap := binary.BigEndian.Uint16(branchData[0:])
   818  	pos := 2
   819  	if deleted {
   820  		// All cells come as deleted (touched but not present after)
   821  		hph.afterMap[row] = 0
   822  		hph.touchMap[row] = bitmap
   823  	} else {
   824  		hph.afterMap[row] = bitmap
   825  		hph.touchMap[row] = 0
   826  	}
   827  	//fmt.Printf("unfoldBranchNode [%x], afterMap = [%016b], touchMap = [%016b]\n", branchData, hph.afterMap[row], hph.touchMap[row])
   828  	// Loop iterating over the set bits of modMask
   829  	for bitset, j := bitmap, 0; bitset != 0; j++ {
   830  		bit := bitset & -bitset
   831  		nibble := bits.TrailingZeros16(bit)
   832  		cell := &hph.grid[row][nibble]
   833  		fieldBits := branchData[pos]
   834  		pos++
   835  		var err error
   836  		if pos, err = cell.fillFromFields(branchData, pos, PartFlags(fieldBits)); err != nil {
   837  			return false, fmt.Errorf("prefix [%x], branchData[%x]: %w", hph.currentKey[:hph.currentKeyLen], branchData, err)
   838  		}
   839  		if hph.trace {
   840  			fmt.Printf("cell (%d, %x) depth=%d, hash=[%x], a=[%x], s=[%x], ex=[%x]\n", row, nibble, depth, cell.h[:cell.hl], cell.apk[:cell.apl], cell.spk[:cell.spl], cell.extension[:cell.extLen])
   841  		}
   842  		if cell.apl > 0 {
   843  			hph.accountFn(cell.apk[:cell.apl], cell)
   844  			if hph.trace {
   845  				fmt.Printf("accountFn[%x] return balance=%d, nonce=%d code=%x\n", cell.apk[:cell.apl], &cell.Balance, cell.Nonce, cell.CodeHash[:])
   846  			}
   847  		}
   848  		if cell.spl > 0 {
   849  			hph.storageFn(cell.spk[:cell.spl], cell)
   850  		}
   851  		if err = cell.deriveHashedKeys(depth, hph.keccak, hph.accountKeyLen); err != nil {
   852  			return false, err
   853  		}
   854  		bitset ^= bit
   855  	}
   856  	return true, nil
   857  }
   858  
   859  func (hph *HexPatriciaHashed) unfold(hashedKey []byte, unfolding int) error {
   860  	if hph.trace {
   861  		fmt.Printf("unfold %d: activeRows: %d\n", unfolding, hph.activeRows)
   862  	}
   863  	var upCell *Cell
   864  	var touched, present bool
   865  	var col byte
   866  	var upDepth, depth int
   867  	if hph.activeRows == 0 {
   868  		if hph.rootChecked && hph.root.hl == 0 && hph.root.downHashedLen == 0 {
   869  			// No unfolding for empty root
   870  			return nil
   871  		}
   872  		upCell = &hph.root
   873  		touched = hph.rootTouched
   874  		present = hph.rootPresent
   875  		if hph.trace {
   876  			fmt.Printf("unfold root, touched %t, present %t, column %d\n", touched, present, col)
   877  		}
   878  	} else {
   879  		upDepth = hph.depths[hph.activeRows-1]
   880  		col = hashedKey[upDepth-1]
   881  		upCell = &hph.grid[hph.activeRows-1][col]
   882  		touched = hph.touchMap[hph.activeRows-1]&(uint16(1)<<col) != 0
   883  		present = hph.afterMap[hph.activeRows-1]&(uint16(1)<<col) != 0
   884  		if hph.trace {
   885  			fmt.Printf("upCell (%d, %x), touched %t, present %t\n", hph.activeRows-1, col, touched, present)
   886  		}
   887  		hph.currentKey[hph.currentKeyLen] = col
   888  		hph.currentKeyLen++
   889  	}
   890  	row := hph.activeRows
   891  	for i := 0; i < 16; i++ {
   892  		hph.grid[row][i].fillEmpty()
   893  	}
   894  	hph.touchMap[row] = 0
   895  	hph.afterMap[row] = 0
   896  	hph.branchBefore[row] = false
   897  	if upCell.downHashedLen == 0 {
   898  		depth = upDepth + 1
   899  		if unfolded, err := hph.unfoldBranchNode(row, touched && !present /* deleted */, depth); err != nil {
   900  			return err
   901  		} else if !unfolded {
   902  			// Return here to prevent activeRow from being incremented
   903  			return nil
   904  		}
   905  	} else if upCell.downHashedLen >= unfolding {
   906  		depth = upDepth + unfolding
   907  		nibble := upCell.downHashedKey[unfolding-1]
   908  		if touched {
   909  			hph.touchMap[row] = uint16(1) << nibble
   910  		}
   911  		if present {
   912  			hph.afterMap[row] = uint16(1) << nibble
   913  		}
   914  		cell := &hph.grid[row][nibble]
   915  		cell.fillFromUpperCell(upCell, depth, unfolding)
   916  		if hph.trace {
   917  			fmt.Printf("cell (%d, %x) depth=%d\n", row, nibble, depth)
   918  		}
   919  		if row >= 64 {
   920  			cell.apl = 0
   921  		}
   922  		if unfolding > 1 {
   923  			copy(hph.currentKey[hph.currentKeyLen:], upCell.downHashedKey[:unfolding-1])
   924  		}
   925  		hph.currentKeyLen += unfolding - 1
   926  	} else {
   927  		// upCell.downHashedLen < unfolding
   928  		depth = upDepth + upCell.downHashedLen
   929  		nibble := upCell.downHashedKey[upCell.downHashedLen-1]
   930  		if touched {
   931  			hph.touchMap[row] = uint16(1) << nibble
   932  		}
   933  		if present {
   934  			hph.afterMap[row] = uint16(1) << nibble
   935  		}
   936  		cell := &hph.grid[row][nibble]
   937  		cell.fillFromUpperCell(upCell, depth, upCell.downHashedLen)
   938  		if hph.trace {
   939  			fmt.Printf("cell (%d, %x) depth=%d\n", row, nibble, depth)
   940  		}
   941  		if row >= 64 {
   942  			cell.apl = 0
   943  		}
   944  		if upCell.downHashedLen > 1 {
   945  			copy(hph.currentKey[hph.currentKeyLen:], upCell.downHashedKey[:upCell.downHashedLen-1])
   946  		}
   947  		hph.currentKeyLen += upCell.downHashedLen - 1
   948  	}
   949  	hph.depths[hph.activeRows] = depth
   950  	hph.activeRows++
   951  	return nil
   952  }
   953  
   954  func (hph *HexPatriciaHashed) needFolding(hashedKey []byte) bool {
   955  	return !bytes.HasPrefix(hashedKey, hph.currentKey[:hph.currentKeyLen])
   956  }
   957  
   958  // The purpose of fold is to reduce hph.currentKey[:hph.currentKeyLen]. It should be invoked
   959  // until that current key becomes a prefix of hashedKey that we will proccess next
   960  // (in other words until the needFolding function returns 0)
   961  func (hph *HexPatriciaHashed) fold() (branchData BranchData, updateKey []byte, err error) {
   962  	updateKeyLen := hph.currentKeyLen
   963  	if hph.activeRows == 0 {
   964  		return nil, nil, fmt.Errorf("cannot fold - no active rows")
   965  	}
   966  	if hph.trace {
   967  		fmt.Printf("fold: activeRows: %d, currentKey: [%x], touchMap: %016b, afterMap: %016b\n", hph.activeRows, hph.currentKey[:hph.currentKeyLen], hph.touchMap[hph.activeRows-1], hph.afterMap[hph.activeRows-1])
   968  	}
   969  	// Move information to the row above
   970  	row := hph.activeRows - 1
   971  	var upCell *Cell
   972  	var col int
   973  	var upDepth int
   974  	if hph.activeRows == 1 {
   975  		if hph.trace {
   976  			fmt.Printf("upcell is root\n")
   977  		}
   978  		upCell = &hph.root
   979  	} else {
   980  		upDepth = hph.depths[hph.activeRows-2]
   981  		col = int(hph.currentKey[upDepth-1])
   982  		if hph.trace {
   983  			fmt.Printf("upcell is (%d x %x), upDepth=%d\n", row-1, col, upDepth)
   984  		}
   985  		upCell = &hph.grid[row-1][col]
   986  	}
   987  
   988  	depth := hph.depths[hph.activeRows-1]
   989  	updateKey = hexToCompact(hph.currentKey[:updateKeyLen])
   990  	partsCount := bits.OnesCount16(hph.afterMap[row])
   991  
   992  	if hph.trace {
   993  		fmt.Printf("touchMap[%d]=%016b, afterMap[%d]=%016b\n", row, hph.touchMap[row], row, hph.afterMap[row])
   994  	}
   995  	switch partsCount {
   996  	case 0:
   997  		// Everything deleted
   998  		if hph.touchMap[row] != 0 {
   999  			if row == 0 {
  1000  				// Root is deleted because the tree is empty
  1001  				hph.rootTouched = true
  1002  				hph.rootPresent = false
  1003  			} else if upDepth == 64 {
  1004  				// Special case - all storage items of an account have been deleted, but it does not automatically delete the account, just makes it empty storage
  1005  				// Therefore we are not propagating deletion upwards, but turn it into a modification
  1006  				hph.touchMap[row-1] |= (uint16(1) << col)
  1007  			} else {
  1008  				// Deletion is propagated upwards
  1009  				hph.touchMap[row-1] |= (uint16(1) << col)
  1010  				hph.afterMap[row-1] &^= (uint16(1) << col)
  1011  			}
  1012  		}
  1013  		upCell.hl = 0
  1014  		upCell.apl = 0
  1015  		upCell.spl = 0
  1016  		upCell.extLen = 0
  1017  		upCell.downHashedLen = 0
  1018  		if hph.branchBefore[row] {
  1019  			branchData, _, err = EncodeBranch(0, hph.touchMap[row], 0, func(nibble int, skip bool) (*Cell, error) { return nil, nil })
  1020  			if err != nil {
  1021  				return nil, updateKey, fmt.Errorf("failed to encode leaf node update: %w", err)
  1022  			}
  1023  		}
  1024  		hph.activeRows--
  1025  		if upDepth > 0 {
  1026  			hph.currentKeyLen = upDepth - 1
  1027  		} else {
  1028  			hph.currentKeyLen = 0
  1029  		}
  1030  	case 1:
  1031  		// Leaf or extension node
  1032  		if hph.touchMap[row] != 0 {
  1033  			// any modifications
  1034  			if row == 0 {
  1035  				hph.rootTouched = true
  1036  			} else {
  1037  				// Modifiction is propagated upwards
  1038  				hph.touchMap[row-1] |= (uint16(1) << col)
  1039  			}
  1040  		}
  1041  		nibble := bits.TrailingZeros16(hph.afterMap[row])
  1042  		cell := &hph.grid[row][nibble]
  1043  		upCell.extLen = 0
  1044  		upCell.fillFromLowerCell(cell, depth, hph.currentKey[upDepth:hph.currentKeyLen], nibble)
  1045  		// Delete if it existed
  1046  		if hph.branchBefore[row] {
  1047  			//branchData, _, err = hph.EncodeBranchDirectAccess(0, row, depth)
  1048  			branchData, _, err = EncodeBranch(0, hph.touchMap[row], 0, func(nibble int, skip bool) (*Cell, error) { return nil, nil })
  1049  			if err != nil {
  1050  				return nil, updateKey, fmt.Errorf("failed to encode leaf node update: %w", err)
  1051  			}
  1052  		}
  1053  		hph.activeRows--
  1054  		if upDepth > 0 {
  1055  			hph.currentKeyLen = upDepth - 1
  1056  		} else {
  1057  			hph.currentKeyLen = 0
  1058  		}
  1059  	default:
  1060  		// Branch node
  1061  		if hph.touchMap[row] != 0 {
  1062  			// any modifications
  1063  			if row == 0 {
  1064  				hph.rootTouched = true
  1065  			} else {
  1066  				// Modifiction is propagated upwards
  1067  				hph.touchMap[row-1] |= (uint16(1) << col)
  1068  			}
  1069  		}
  1070  		bitmap := hph.touchMap[row] & hph.afterMap[row]
  1071  		if !hph.branchBefore[row] {
  1072  			// There was no branch node before, so we need to touch even the singular child that existed
  1073  			hph.touchMap[row] |= hph.afterMap[row]
  1074  			bitmap |= hph.afterMap[row]
  1075  		}
  1076  		// Calculate total length of all hashes
  1077  		totalBranchLen := 17 - partsCount // For every empty cell, one byte
  1078  		for bitset, j := hph.afterMap[row], 0; bitset != 0; j++ {
  1079  			bit := bitset & -bitset
  1080  			nibble := bits.TrailingZeros16(bit)
  1081  			cell := &hph.grid[row][nibble]
  1082  			totalBranchLen += hph.computeCellHashLen(cell, depth)
  1083  			bitset ^= bit
  1084  		}
  1085  
  1086  		hph.keccak2.Reset()
  1087  		pt := rlp.GenerateStructLen(hph.hashAuxBuffer[:], totalBranchLen)
  1088  		if _, err := hph.keccak2.Write(hph.hashAuxBuffer[:pt]); err != nil {
  1089  			return nil, nil, err
  1090  		}
  1091  
  1092  		b := [...]byte{0x80}
  1093  		cellGetter := func(nibble int, skip bool) (*Cell, error) {
  1094  			if skip {
  1095  				if _, err := hph.keccak2.Write(b[:]); err != nil {
  1096  					return nil, fmt.Errorf("failed to write empty nibble to hash: %w", err)
  1097  				}
  1098  				if hph.trace {
  1099  					fmt.Printf("%x: empty(%d,%x)\n", nibble, row, nibble)
  1100  				}
  1101  				return nil, nil
  1102  			}
  1103  			cell := &hph.grid[row][nibble]
  1104  			cellHash, err := hph.computeCellHash(cell, depth, hph.hashAuxBuffer[:0])
  1105  			if err != nil {
  1106  				return nil, err
  1107  			}
  1108  			if hph.trace {
  1109  				fmt.Printf("%x: computeCellHash(%d,%x,depth=%d)=[%x]\n", nibble, row, nibble, depth, cellHash)
  1110  			}
  1111  			if _, err := hph.keccak2.Write(cellHash); err != nil {
  1112  				return nil, err
  1113  			}
  1114  
  1115  			return cell, nil
  1116  		}
  1117  
  1118  		var lastNibble int
  1119  		var err error
  1120  		_ = cellGetter
  1121  
  1122  		//branchData, lastNibble, err = hph.EncodeBranchDirectAccess(bitmap, row, depth, branchData)
  1123  		branchData, lastNibble, err = EncodeBranch(bitmap, hph.touchMap[row], hph.afterMap[row], cellGetter)
  1124  		if err != nil {
  1125  			return nil, nil, fmt.Errorf("failed to encode branch update: %w", err)
  1126  		}
  1127  		for i := lastNibble; i < 17; i++ {
  1128  			if _, err := hph.keccak2.Write(b[:]); err != nil {
  1129  				return nil, nil, err
  1130  			}
  1131  			if hph.trace {
  1132  				fmt.Printf("%x: empty(%d,%x)\n", i, row, i)
  1133  			}
  1134  		}
  1135  		upCell.extLen = depth - upDepth - 1
  1136  		upCell.downHashedLen = upCell.extLen
  1137  		if upCell.extLen > 0 {
  1138  			copy(upCell.extension[:], hph.currentKey[upDepth:hph.currentKeyLen])
  1139  			copy(upCell.downHashedKey[:], hph.currentKey[upDepth:hph.currentKeyLen])
  1140  		}
  1141  		if depth < 64 {
  1142  			upCell.apl = 0
  1143  		}
  1144  		upCell.spl = 0
  1145  		upCell.hl = 32
  1146  		if _, err := hph.keccak2.Read(upCell.h[:]); err != nil {
  1147  			return nil, nil, err
  1148  		}
  1149  		if hph.trace {
  1150  			fmt.Printf("} [%x]\n", upCell.h[:])
  1151  		}
  1152  		hph.activeRows--
  1153  		if upDepth > 0 {
  1154  			hph.currentKeyLen = upDepth - 1
  1155  		} else {
  1156  			hph.currentKeyLen = 0
  1157  		}
  1158  	}
  1159  	if branchData != nil {
  1160  		if hph.trace {
  1161  			fmt.Printf("fold: update key: %x, branchData: [%x]\n", CompactedKeyToHex(updateKey), branchData)
  1162  		}
  1163  	}
  1164  	return branchData, updateKey, nil
  1165  }
  1166  
  1167  func (hph *HexPatriciaHashed) deleteCell(hashedKey []byte) {
  1168  	if hph.trace {
  1169  		fmt.Printf("deleteCell, activeRows = %d\n", hph.activeRows)
  1170  	}
  1171  	var cell *Cell
  1172  	if hph.activeRows == 0 {
  1173  		// Remove the root
  1174  		cell = &hph.root
  1175  		hph.rootTouched = true
  1176  		hph.rootPresent = false
  1177  	} else {
  1178  		row := hph.activeRows - 1
  1179  		if hph.depths[row] < len(hashedKey) {
  1180  			if hph.trace {
  1181  				fmt.Printf("deleteCell skipping spurious delete depth=%d, len(hashedKey)=%d\n", hph.depths[row], len(hashedKey))
  1182  			}
  1183  			return
  1184  		}
  1185  		col := int(hashedKey[hph.currentKeyLen])
  1186  		cell = &hph.grid[row][col]
  1187  		if hph.afterMap[row]&(uint16(1)<<col) != 0 {
  1188  			// Prevent "spurios deletions", i.e. deletion of absent items
  1189  			hph.touchMap[row] |= (uint16(1) << col)
  1190  			hph.afterMap[row] &^= (uint16(1) << col)
  1191  			if hph.trace {
  1192  				fmt.Printf("deleteCell setting (%d, %x)\n", row, col)
  1193  			}
  1194  		} else {
  1195  			if hph.trace {
  1196  				fmt.Printf("deleteCell ignoring (%d, %x)\n", row, col)
  1197  			}
  1198  		}
  1199  	}
  1200  	cell.extLen = 0
  1201  	cell.Balance.Clear()
  1202  	copy(cell.CodeHash[:], EmptyCodeHash)
  1203  	cell.Nonce = 0
  1204  }
  1205  
  1206  func (hph *HexPatriciaHashed) updateCell(plainKey, hashedKey []byte) *Cell {
  1207  	var cell *Cell
  1208  	var col, depth int
  1209  	if hph.activeRows == 0 {
  1210  		cell = &hph.root
  1211  		hph.rootTouched, hph.rootPresent = true, true
  1212  	} else {
  1213  		row := hph.activeRows - 1
  1214  		depth = hph.depths[row]
  1215  		col = int(hashedKey[hph.currentKeyLen])
  1216  		cell = &hph.grid[row][col]
  1217  		hph.touchMap[row] |= (uint16(1) << col)
  1218  		hph.afterMap[row] |= (uint16(1) << col)
  1219  		if hph.trace {
  1220  			fmt.Printf("updateCell setting (%d, %x), depth=%d\n", row, col, depth)
  1221  		}
  1222  	}
  1223  	if cell.downHashedLen == 0 {
  1224  		copy(cell.downHashedKey[:], hashedKey[depth:])
  1225  		cell.downHashedLen = len(hashedKey) - depth
  1226  		if hph.trace {
  1227  			fmt.Printf("set downHasheKey=[%x]\n", cell.downHashedKey[:cell.downHashedLen])
  1228  		}
  1229  	} else {
  1230  		if hph.trace {
  1231  			fmt.Printf("left downHasheKey=[%x]\n", cell.downHashedKey[:cell.downHashedLen])
  1232  		}
  1233  	}
  1234  	if len(hashedKey) == 2*length.Hash { // set account key
  1235  		cell.apl = len(plainKey)
  1236  		copy(cell.apk[:], plainKey)
  1237  	} else { // set storage key
  1238  		cell.spl = len(plainKey)
  1239  		copy(cell.spk[:], plainKey)
  1240  	}
  1241  	return cell
  1242  }
  1243  
  1244  func (hph *HexPatriciaHashed) RootHash() ([]byte, error) {
  1245  	hash, err := hph.computeCellHash(&hph.root, 0, nil)
  1246  	if err != nil {
  1247  		return nil, err
  1248  	}
  1249  	return hash[1:], nil // first byte is 128+hash_len
  1250  }
  1251  
  1252  func (hph *HexPatriciaHashed) ReviewKeys(plainKeys, hashedKeys [][]byte) (rootHash []byte, branchNodeUpdates map[string]BranchData, err error) {
  1253  	branchNodeUpdates = make(map[string]BranchData)
  1254  
  1255  	stagedCell := new(Cell)
  1256  	for i, hashedKey := range hashedKeys {
  1257  		plainKey := plainKeys[i]
  1258  		if hph.trace {
  1259  			fmt.Printf("plainKey=[%x], hashedKey=[%x], currentKey=[%x]\n", plainKey, hashedKey, hph.currentKey[:hph.currentKeyLen])
  1260  		}
  1261  		// Keep folding until the currentKey is the prefix of the key we modify
  1262  		for hph.needFolding(hashedKey) {
  1263  			if branchData, updateKey, err := hph.fold(); err != nil {
  1264  				return nil, nil, fmt.Errorf("fold: %w", err)
  1265  			} else if branchData != nil {
  1266  				branchNodeUpdates[string(updateKey)] = branchData
  1267  			}
  1268  		}
  1269  		// Now unfold until we step on an empty cell
  1270  		for unfolding := hph.needUnfolding(hashedKey); unfolding > 0; unfolding = hph.needUnfolding(hashedKey) {
  1271  			if err := hph.unfold(hashedKey, unfolding); err != nil {
  1272  				return nil, nil, fmt.Errorf("unfold: %w", err)
  1273  			}
  1274  		}
  1275  
  1276  		// Update the cell
  1277  		stagedCell.fillEmpty()
  1278  		if len(plainKey) == hph.accountKeyLen {
  1279  			if err := hph.accountFn(plainKey, stagedCell); err != nil {
  1280  				return nil, nil, fmt.Errorf("accountFn for key %x failed: %w", plainKey, err)
  1281  			}
  1282  			if !stagedCell.Delete {
  1283  				cell := hph.updateCell(plainKey, hashedKey)
  1284  				cell.setAccountFields(stagedCell.CodeHash[:], &stagedCell.Balance, stagedCell.Nonce)
  1285  
  1286  				if hph.trace {
  1287  					fmt.Printf("accountFn reading key %x => balance=%v nonce=%v codeHash=%x\n", cell.apk, cell.Balance.Uint64(), cell.Nonce, cell.CodeHash)
  1288  				}
  1289  			}
  1290  		} else {
  1291  			if err = hph.storageFn(plainKey, stagedCell); err != nil {
  1292  				return nil, nil, fmt.Errorf("storageFn for key %x failed: %w", plainKey, err)
  1293  			}
  1294  			if !stagedCell.Delete {
  1295  				hph.updateCell(plainKey, hashedKey).setStorage(stagedCell.Storage[:stagedCell.StorageLen])
  1296  				if hph.trace {
  1297  					fmt.Printf("storageFn reading key %x => %x\n", plainKey, stagedCell.Storage[:stagedCell.StorageLen])
  1298  				}
  1299  			}
  1300  		}
  1301  
  1302  		if stagedCell.Delete {
  1303  			if hph.trace {
  1304  				fmt.Printf("delete cell %x hash %x\n", plainKey, hashedKey)
  1305  			}
  1306  			hph.deleteCell(hashedKey)
  1307  		}
  1308  	}
  1309  	// Folding everything up to the root
  1310  	for hph.activeRows > 0 {
  1311  		if branchData, updateKey, err := hph.fold(); err != nil {
  1312  			return nil, nil, fmt.Errorf("final fold: %w", err)
  1313  		} else if branchData != nil {
  1314  			branchNodeUpdates[string(updateKey)] = branchData
  1315  		}
  1316  	}
  1317  
  1318  	rootHash, err = hph.RootHash()
  1319  	if err != nil {
  1320  		return nil, branchNodeUpdates, fmt.Errorf("root hash evaluation failed: %w", err)
  1321  	}
  1322  	return rootHash, branchNodeUpdates, nil
  1323  }
  1324  
  1325  func (hph *HexPatriciaHashed) SetTrace(trace bool) { hph.trace = trace }
  1326  
  1327  func (hph *HexPatriciaHashed) Variant() TrieVariant { return VariantHexPatriciaTrie }
  1328  
  1329  // Reset allows HexPatriciaHashed instance to be reused for the new commitment calculation
  1330  func (hph *HexPatriciaHashed) Reset() {
  1331  	hph.rootChecked = false
  1332  	hph.root.hl = 0
  1333  	hph.root.downHashedLen = 0
  1334  	hph.root.apl = 0
  1335  	hph.root.spl = 0
  1336  	hph.root.extLen = 0
  1337  	copy(hph.root.CodeHash[:], EmptyCodeHash)
  1338  	hph.root.StorageLen = 0
  1339  	hph.root.Balance.Clear()
  1340  	hph.root.Nonce = 0
  1341  	hph.rootTouched = false
  1342  	hph.rootPresent = true
  1343  }
  1344  
  1345  func (hph *HexPatriciaHashed) ResetFns(
  1346  	branchFn func(prefix []byte) ([]byte, error),
  1347  	accountFn func(plainKey []byte, cell *Cell) error,
  1348  	storageFn func(plainKey []byte, cell *Cell) error,
  1349  ) {
  1350  	hph.branchFn = branchFn
  1351  	hph.accountFn = accountFn
  1352  	hph.storageFn = storageFn
  1353  }
  1354  
  1355  type stateRootFlag int8
  1356  
  1357  var (
  1358  	stateRootPresent stateRootFlag = 1
  1359  	stateRootChecked stateRootFlag = 2
  1360  	stateRootTouched stateRootFlag = 4
  1361  )
  1362  
  1363  func (s *state) Encode(buf []byte) ([]byte, error) {
  1364  	var rootFlags stateRootFlag
  1365  	if s.RootPresent {
  1366  		rootFlags |= stateRootPresent
  1367  	}
  1368  	if s.RootChecked {
  1369  		rootFlags |= stateRootChecked
  1370  	}
  1371  	if s.RootTouched {
  1372  		rootFlags |= stateRootTouched
  1373  	}
  1374  
  1375  	ee := bytes.NewBuffer(buf)
  1376  	if err := binary.Write(ee, binary.BigEndian, s.CurrentKeyLen); err != nil {
  1377  		return nil, fmt.Errorf("encode currentKeyLen: %w", err)
  1378  	}
  1379  	if err := binary.Write(ee, binary.BigEndian, int8(rootFlags)); err != nil {
  1380  		return nil, fmt.Errorf("encode rootFlags: %w", err)
  1381  	}
  1382  	if n, err := ee.Write(s.CurrentKey[:]); err != nil || n != len(s.CurrentKey) {
  1383  		return nil, fmt.Errorf("encode currentKey: %w", err)
  1384  	}
  1385  	if err := binary.Write(ee, binary.BigEndian, uint16(len(s.Root))); err != nil {
  1386  		return nil, fmt.Errorf("encode root len: %w", err)
  1387  	}
  1388  	if n, err := ee.Write(s.Root); err != nil || n != len(s.Root) {
  1389  		return nil, fmt.Errorf("encode root: %w", err)
  1390  	}
  1391  	d := make([]byte, len(s.Depths))
  1392  	for i := 0; i < len(s.Depths); i++ {
  1393  		d[i] = byte(s.Depths[i])
  1394  	}
  1395  	if n, err := ee.Write(d); err != nil || n != len(s.Depths) {
  1396  		return nil, fmt.Errorf("encode depths: %w", err)
  1397  	}
  1398  	if err := binary.Write(ee, binary.BigEndian, s.TouchMap); err != nil {
  1399  		return nil, fmt.Errorf("encode touchMap: %w", err)
  1400  	}
  1401  	if err := binary.Write(ee, binary.BigEndian, s.AfterMap); err != nil {
  1402  		return nil, fmt.Errorf("encode afterMap: %w", err)
  1403  	}
  1404  
  1405  	var before1, before2 uint64
  1406  	for i := 0; i < 64; i++ {
  1407  		if s.BranchBefore[i] {
  1408  			before1 |= 1 << i
  1409  		}
  1410  	}
  1411  	for i, j := 64, 0; i < 128; i, j = i+1, j+1 {
  1412  		if s.BranchBefore[i] {
  1413  			before2 |= 1 << j
  1414  		}
  1415  	}
  1416  	if err := binary.Write(ee, binary.BigEndian, before1); err != nil {
  1417  		return nil, fmt.Errorf("encode branchBefore_1: %w", err)
  1418  	}
  1419  	if err := binary.Write(ee, binary.BigEndian, before2); err != nil {
  1420  		return nil, fmt.Errorf("encode branchBefore_2: %w", err)
  1421  	}
  1422  	return ee.Bytes(), nil
  1423  }
  1424  
  1425  func (s *state) Decode(buf []byte) error {
  1426  	aux := bytes.NewBuffer(buf)
  1427  	if err := binary.Read(aux, binary.BigEndian, &s.CurrentKeyLen); err != nil {
  1428  		return fmt.Errorf("currentKeyLen: %w", err)
  1429  	}
  1430  	var rootFlags stateRootFlag
  1431  	if err := binary.Read(aux, binary.BigEndian, &rootFlags); err != nil {
  1432  		return fmt.Errorf("rootFlags: %w", err)
  1433  	}
  1434  
  1435  	if rootFlags&stateRootPresent != 0 {
  1436  		s.RootPresent = true
  1437  	}
  1438  	if rootFlags&stateRootTouched != 0 {
  1439  		s.RootTouched = true
  1440  	}
  1441  	if rootFlags&stateRootChecked != 0 {
  1442  		s.RootChecked = true
  1443  	}
  1444  	if n, err := aux.Read(s.CurrentKey[:]); err != nil || n != 128 {
  1445  		return fmt.Errorf("currentKey: %w", err)
  1446  	}
  1447  	var rootSize uint16
  1448  	if err := binary.Read(aux, binary.BigEndian, &rootSize); err != nil {
  1449  		return fmt.Errorf("root size: %w", err)
  1450  	}
  1451  	s.Root = make([]byte, rootSize)
  1452  	if _, err := aux.Read(s.Root); err != nil {
  1453  		return fmt.Errorf("root: %w", err)
  1454  	}
  1455  	d := make([]byte, len(s.Depths))
  1456  	if err := binary.Read(aux, binary.BigEndian, &d); err != nil {
  1457  		return fmt.Errorf("depths: %w", err)
  1458  	}
  1459  	for i := 0; i < len(s.Depths); i++ {
  1460  		s.Depths[i] = int(d[i])
  1461  	}
  1462  	if err := binary.Read(aux, binary.BigEndian, &s.TouchMap); err != nil {
  1463  		return fmt.Errorf("touchMap: %w", err)
  1464  	}
  1465  	if err := binary.Read(aux, binary.BigEndian, &s.AfterMap); err != nil {
  1466  		return fmt.Errorf("afterMap: %w", err)
  1467  	}
  1468  	var branch1, branch2 uint64
  1469  	if err := binary.Read(aux, binary.BigEndian, &branch1); err != nil {
  1470  		return fmt.Errorf("branchBefore1: %w", err)
  1471  	}
  1472  	if err := binary.Read(aux, binary.BigEndian, &branch2); err != nil {
  1473  		return fmt.Errorf("branchBefore2: %w", err)
  1474  	}
  1475  
  1476  	for i := 0; i < 64; i++ {
  1477  		if branch1&(1<<i) != 0 {
  1478  			s.BranchBefore[i] = true
  1479  		}
  1480  	}
  1481  	for i, j := 64, 0; i < 128; i, j = i+1, j+1 {
  1482  		if branch2&(1<<j) != 0 {
  1483  			s.BranchBefore[i] = true
  1484  		}
  1485  	}
  1486  	return nil
  1487  }
  1488  
  1489  func (c *Cell) bytes() []byte {
  1490  	var pos = 1
  1491  	size := 1 + c.hl + 1 + c.apl + c.spl + 1 + c.downHashedLen + 1 + c.extLen + 1 // max size
  1492  	buf := make([]byte, size)
  1493  
  1494  	var flags uint8
  1495  	if c.hl != 0 {
  1496  		flags |= 1
  1497  		buf[pos] = byte(c.hl)
  1498  		pos++
  1499  		copy(buf[pos:pos+c.hl], c.h[:])
  1500  		pos += c.hl
  1501  	}
  1502  	if c.apl != 0 {
  1503  		flags |= 2
  1504  		buf[pos] = byte(c.hl)
  1505  		pos++
  1506  		copy(buf[pos:pos+c.apl], c.apk[:])
  1507  		pos += c.apl
  1508  	}
  1509  	if c.spl != 0 {
  1510  		flags |= 4
  1511  		buf[pos] = byte(c.spl)
  1512  		pos++
  1513  		copy(buf[pos:pos+c.spl], c.spk[:])
  1514  		pos += c.spl
  1515  	}
  1516  	if c.downHashedLen != 0 {
  1517  		flags |= 8
  1518  		buf[pos] = byte(c.downHashedLen)
  1519  		pos++
  1520  		copy(buf[pos:pos+c.downHashedLen], c.downHashedKey[:])
  1521  		pos += c.downHashedLen
  1522  	}
  1523  	if c.extLen != 0 {
  1524  		flags |= 16
  1525  		buf[pos] = byte(c.extLen)
  1526  		pos++
  1527  		copy(buf[pos:pos+c.downHashedLen], c.downHashedKey[:])
  1528  		//pos += c.downHashedLen
  1529  	}
  1530  	buf[0] = flags
  1531  	return buf
  1532  }
  1533  
  1534  func (c *Cell) decodeBytes(buf []byte) error {
  1535  	if len(buf) < 1 {
  1536  		return fmt.Errorf("invalid buffer size to contain Cell (at least 1 byte expected)")
  1537  	}
  1538  	c.fillEmpty()
  1539  
  1540  	var pos int
  1541  	flags := buf[pos]
  1542  	pos++
  1543  
  1544  	if flags&1 != 0 {
  1545  		c.hl = int(buf[pos])
  1546  		pos++
  1547  		copy(c.h[:], buf[pos:pos+c.hl])
  1548  		pos += c.hl
  1549  	}
  1550  	if flags&2 != 0 {
  1551  		c.apl = int(buf[pos])
  1552  		pos++
  1553  		copy(c.apk[:], buf[pos:pos+c.apl])
  1554  		pos += c.apl
  1555  	}
  1556  	if flags&4 != 0 {
  1557  		c.spl = int(buf[pos])
  1558  		pos++
  1559  		copy(c.spk[:], buf[pos:pos+c.spl])
  1560  		pos += c.spl
  1561  	}
  1562  	if flags&8 != 0 {
  1563  		c.downHashedLen = int(buf[pos])
  1564  		pos++
  1565  		copy(c.downHashedKey[:], buf[pos:pos+c.downHashedLen])
  1566  		pos += c.downHashedLen
  1567  	}
  1568  	if flags&16 != 0 {
  1569  		c.extLen = int(buf[pos])
  1570  		pos++
  1571  		copy(c.extension[:], buf[pos:pos+c.extLen])
  1572  		//pos += c.extLen
  1573  	}
  1574  	return nil
  1575  }
  1576  
  1577  // Encode current state of hph into bytes
  1578  func (hph *HexPatriciaHashed) EncodeCurrentState(buf []byte) ([]byte, error) {
  1579  	s := state{
  1580  		CurrentKeyLen: int8(hph.currentKeyLen),
  1581  		RootChecked:   hph.rootChecked,
  1582  		RootTouched:   hph.rootTouched,
  1583  		RootPresent:   hph.rootPresent,
  1584  		Root:          make([]byte, 0),
  1585  	}
  1586  
  1587  	s.Root = hph.root.bytes()
  1588  	copy(s.CurrentKey[:], hph.currentKey[:])
  1589  	copy(s.Depths[:], hph.depths[:])
  1590  	copy(s.BranchBefore[:], hph.branchBefore[:])
  1591  	copy(s.TouchMap[:], hph.touchMap[:])
  1592  	copy(s.AfterMap[:], hph.afterMap[:])
  1593  
  1594  	return s.Encode(buf)
  1595  }
  1596  
  1597  // buf expected to be encoded hph state. Decode state and set up hph to that state.
  1598  func (hph *HexPatriciaHashed) SetState(buf []byte) error {
  1599  	if hph.activeRows != 0 {
  1600  		return fmt.Errorf("has active rows, could not reset state")
  1601  	}
  1602  
  1603  	var s state
  1604  	if err := s.Decode(buf); err != nil {
  1605  		return err
  1606  	}
  1607  
  1608  	hph.Reset()
  1609  
  1610  	if err := hph.root.decodeBytes(s.Root); err != nil {
  1611  		return err
  1612  	}
  1613  
  1614  	hph.currentKeyLen = int(s.CurrentKeyLen)
  1615  	hph.rootChecked = s.RootChecked
  1616  	hph.rootTouched = s.RootTouched
  1617  	hph.rootPresent = s.RootPresent
  1618  
  1619  	copy(hph.currentKey[:], s.CurrentKey[:])
  1620  	copy(hph.depths[:], s.Depths[:])
  1621  	copy(hph.branchBefore[:], s.BranchBefore[:])
  1622  	copy(hph.touchMap[:], s.TouchMap[:])
  1623  	copy(hph.afterMap[:], s.AfterMap[:])
  1624  
  1625  	return nil
  1626  }
  1627  
  1628  func bytesToUint64(buf []byte) (x uint64) {
  1629  	for i, b := range buf {
  1630  		x = x<<8 + uint64(b)
  1631  		if i == 7 {
  1632  			return
  1633  		}
  1634  	}
  1635  	return
  1636  }
  1637  
  1638  func hexToCompact(key []byte) []byte {
  1639  	zeroByte, keyPos, keyLen := makeCompactZeroByte(key)
  1640  	bufLen := keyLen/2 + 1 // always > 0
  1641  	buf := make([]byte, bufLen)
  1642  	buf[0] = zeroByte
  1643  	return decodeKey(key[keyPos:], buf)
  1644  }
  1645  
  1646  func makeCompactZeroByte(key []byte) (compactZeroByte byte, keyPos, keyLen int) {
  1647  	keyLen = len(key)
  1648  	if hasTerm(key) {
  1649  		keyLen--
  1650  		compactZeroByte = 0x20
  1651  	}
  1652  	var firstNibble byte
  1653  	if len(key) > 0 {
  1654  		firstNibble = key[0]
  1655  	}
  1656  	if keyLen&1 == 1 {
  1657  		compactZeroByte |= 0x10 | firstNibble // Odd: (1<<4) + first nibble
  1658  		keyPos++
  1659  	}
  1660  
  1661  	return
  1662  }
  1663  
  1664  func decodeKey(key, buf []byte) []byte {
  1665  	keyLen := len(key)
  1666  	if hasTerm(key) {
  1667  		keyLen--
  1668  	}
  1669  	for keyIndex, bufIndex := 0, 1; keyIndex < keyLen; keyIndex, bufIndex = keyIndex+2, bufIndex+1 {
  1670  		if keyIndex == keyLen-1 {
  1671  			buf[bufIndex] = buf[bufIndex] & 0x0f
  1672  		} else {
  1673  			buf[bufIndex] = key[keyIndex+1]
  1674  		}
  1675  		buf[bufIndex] |= key[keyIndex] << 4
  1676  	}
  1677  	return buf
  1678  }
  1679  
  1680  func CompactedKeyToHex(compact []byte) []byte {
  1681  	if len(compact) == 0 {
  1682  		return compact
  1683  	}
  1684  	base := keybytesToHexNibbles(compact)
  1685  	// delete terminator flag
  1686  	if base[0] < 2 {
  1687  		base = base[:len(base)-1]
  1688  	}
  1689  	// apply odd flag
  1690  	chop := 2 - base[0]&1
  1691  	return base[chop:]
  1692  }
  1693  
  1694  func keybytesToHexNibbles(str []byte) []byte {
  1695  	l := len(str)*2 + 1
  1696  	var nibbles = make([]byte, l)
  1697  	for i, b := range str {
  1698  		nibbles[i*2] = b / 16
  1699  		nibbles[i*2+1] = b % 16
  1700  	}
  1701  	nibbles[l-1] = 16
  1702  	return nibbles
  1703  }
  1704  
  1705  // hasTerm returns whether a hex key has the terminator flag.
  1706  func hasTerm(s []byte) bool {
  1707  	return len(s) > 0 && s[len(s)-1] == 16
  1708  }
  1709  
  1710  func commonPrefixLen(b1, b2 []byte) int {
  1711  	var i int
  1712  	for i = 0; i < len(b1) && i < len(b2); i++ {
  1713  		if b1[i] != b2[i] {
  1714  			break
  1715  		}
  1716  	}
  1717  	return i
  1718  }
  1719  
  1720  func (hph *HexPatriciaHashed) ProcessUpdates(plainKeys, hashedKeys [][]byte, updates []Update) (rootHash []byte, branchNodeUpdates map[string]BranchData, err error) {
  1721  	branchNodeUpdates = make(map[string]BranchData)
  1722  
  1723  	for i, plainKey := range plainKeys {
  1724  		hashedKey := hashedKeys[i]
  1725  		if hph.trace {
  1726  			fmt.Printf("plainKey=[%x], hashedKey=[%x], currentKey=[%x]\n", plainKey, hashedKey, hph.currentKey[:hph.currentKeyLen])
  1727  		}
  1728  		// Keep folding until the currentKey is the prefix of the key we modify
  1729  		for hph.needFolding(hashedKey) {
  1730  			if branchData, updateKey, err := hph.fold(); err != nil {
  1731  				return nil, nil, fmt.Errorf("fold: %w", err)
  1732  			} else if branchData != nil {
  1733  				branchNodeUpdates[string(updateKey)] = branchData
  1734  			}
  1735  		}
  1736  		// Now unfold until we step on an empty cell
  1737  		for unfolding := hph.needUnfolding(hashedKey); unfolding > 0; unfolding = hph.needUnfolding(hashedKey) {
  1738  			if err := hph.unfold(hashedKey, unfolding); err != nil {
  1739  				return nil, nil, fmt.Errorf("unfold: %w", err)
  1740  			}
  1741  		}
  1742  
  1743  		update := updates[i]
  1744  		// Update the cell
  1745  		if update.Flags == DeleteUpdate {
  1746  			hph.deleteCell(hashedKey)
  1747  			if hph.trace {
  1748  				fmt.Printf("key %x deleted\n", plainKey)
  1749  			}
  1750  		} else {
  1751  			cell := hph.updateCell(plainKey, hashedKey)
  1752  			if hph.trace {
  1753  				fmt.Printf("accountFn updated key %x =>", plainKey)
  1754  			}
  1755  			if update.Flags&BalanceUpdate != 0 {
  1756  				if hph.trace {
  1757  					fmt.Printf(" balance=%d", update.Balance.Uint64())
  1758  				}
  1759  				cell.Balance.Set(&update.Balance)
  1760  			}
  1761  			if update.Flags&NonceUpdate != 0 {
  1762  				if hph.trace {
  1763  					fmt.Printf(" nonce=%d", update.Nonce)
  1764  				}
  1765  				cell.Nonce = update.Nonce
  1766  			}
  1767  			if update.Flags&CodeUpdate != 0 {
  1768  				if hph.trace {
  1769  					fmt.Printf(" codeHash=%x", update.CodeHashOrStorage)
  1770  				}
  1771  				copy(cell.CodeHash[:], update.CodeHashOrStorage[:])
  1772  			}
  1773  			if hph.trace {
  1774  				fmt.Printf("\n")
  1775  			}
  1776  			if update.Flags&StorageUpdate != 0 {
  1777  				cell.setStorage(update.CodeHashOrStorage[:update.ValLength])
  1778  				if hph.trace {
  1779  					fmt.Printf("\rstorageFn filled key %x => %x\n", plainKey, update.CodeHashOrStorage[:update.ValLength])
  1780  				}
  1781  			}
  1782  		}
  1783  	}
  1784  	// Folding everything up to the root
  1785  	for hph.activeRows > 0 {
  1786  		if branchData, updateKey, err := hph.fold(); err != nil {
  1787  			return nil, nil, fmt.Errorf("final fold: %w", err)
  1788  		} else if branchData != nil {
  1789  			branchNodeUpdates[string(updateKey)] = branchData
  1790  		}
  1791  	}
  1792  
  1793  	rootHash, err = hph.RootHash()
  1794  	if err != nil {
  1795  		return nil, branchNodeUpdates, fmt.Errorf("root hash evaluation failed: %w", err)
  1796  	}
  1797  	return rootHash, branchNodeUpdates, nil
  1798  }
  1799  
  1800  // nolint
  1801  // Hashes provided key and expands resulting hash into nibbles (each byte split into two nibbles by 4 bits)
  1802  func (hph *HexPatriciaHashed) hashAndNibblizeKey(key []byte) []byte {
  1803  	hashedKey := make([]byte, length.Hash)
  1804  
  1805  	hph.keccak.Reset()
  1806  	hph.keccak.Write(key[:length.Addr])
  1807  	copy(hashedKey[:length.Hash], hph.keccak.Sum(nil))
  1808  
  1809  	if len(key[length.Addr:]) > 0 {
  1810  		hashedKey = append(hashedKey, make([]byte, length.Hash)...)
  1811  		hph.keccak.Reset()
  1812  		hph.keccak.Write(key[length.Addr:])
  1813  		copy(hashedKey[length.Hash:], hph.keccak.Sum(nil))
  1814  	}
  1815  
  1816  	nibblized := make([]byte, len(hashedKey)*2)
  1817  	for i, b := range hashedKey {
  1818  		nibblized[i*2] = (b >> 4) & 0xf
  1819  		nibblized[i*2+1] = b & 0xf
  1820  	}
  1821  	return nibblized
  1822  }
  1823  
  1824  type UpdateFlags uint8
  1825  
  1826  const (
  1827  	CodeUpdate    UpdateFlags = 1
  1828  	DeleteUpdate  UpdateFlags = 2
  1829  	BalanceUpdate UpdateFlags = 4
  1830  	NonceUpdate   UpdateFlags = 8
  1831  	StorageUpdate UpdateFlags = 16
  1832  )
  1833  
  1834  func (uf UpdateFlags) String() string {
  1835  	var sb strings.Builder
  1836  	if uf == DeleteUpdate {
  1837  		sb.WriteString("Delete")
  1838  	} else {
  1839  		if uf&BalanceUpdate != 0 {
  1840  			sb.WriteString("+Balance")
  1841  		}
  1842  		if uf&NonceUpdate != 0 {
  1843  			sb.WriteString("+Nonce")
  1844  		}
  1845  		if uf&CodeUpdate != 0 {
  1846  			sb.WriteString("+Code")
  1847  		}
  1848  		if uf&StorageUpdate != 0 {
  1849  			sb.WriteString("+Storage")
  1850  		}
  1851  	}
  1852  	return sb.String()
  1853  }
  1854  
  1855  type Update struct {
  1856  	Flags             UpdateFlags
  1857  	Balance           uint256.Int
  1858  	Nonce             uint64
  1859  	CodeHashOrStorage [length.Hash]byte
  1860  	ValLength         int
  1861  }
  1862  
  1863  func (u *Update) DecodeForStorage(enc []byte) {
  1864  	u.Nonce = 0
  1865  	u.Balance.Clear()
  1866  	copy(u.CodeHashOrStorage[:], EmptyCodeHash)
  1867  
  1868  	pos := 0
  1869  	nonceBytes := int(enc[pos])
  1870  	pos++
  1871  	if nonceBytes > 0 {
  1872  		u.Nonce = bytesToUint64(enc[pos : pos+nonceBytes])
  1873  		pos += nonceBytes
  1874  	}
  1875  	balanceBytes := int(enc[pos])
  1876  	pos++
  1877  	if balanceBytes > 0 {
  1878  		u.Balance.SetBytes(enc[pos : pos+balanceBytes])
  1879  		pos += balanceBytes
  1880  	}
  1881  	codeHashBytes := int(enc[pos])
  1882  	pos++
  1883  	if codeHashBytes > 0 {
  1884  		copy(u.CodeHashOrStorage[:], enc[pos:pos+codeHashBytes])
  1885  	}
  1886  }
  1887  
  1888  func (u *Update) Encode(buf []byte, numBuf []byte) []byte {
  1889  	buf = append(buf, byte(u.Flags))
  1890  	if u.Flags&BalanceUpdate != 0 {
  1891  		buf = append(buf, byte(u.Balance.ByteLen()))
  1892  		buf = append(buf, u.Balance.Bytes()...)
  1893  	}
  1894  	if u.Flags&NonceUpdate != 0 {
  1895  		n := binary.PutUvarint(numBuf, u.Nonce)
  1896  		buf = append(buf, numBuf[:n]...)
  1897  	}
  1898  	if u.Flags&CodeUpdate != 0 {
  1899  		buf = append(buf, u.CodeHashOrStorage[:]...)
  1900  	}
  1901  	if u.Flags&StorageUpdate != 0 {
  1902  		n := binary.PutUvarint(numBuf, uint64(u.ValLength))
  1903  		buf = append(buf, numBuf[:n]...)
  1904  		if u.ValLength > 0 {
  1905  			buf = append(buf, u.CodeHashOrStorage[:u.ValLength]...)
  1906  		}
  1907  	}
  1908  	return buf
  1909  }
  1910  
  1911  func (u *Update) Decode(buf []byte, pos int) (int, error) {
  1912  	if len(buf) < pos+1 {
  1913  		return 0, fmt.Errorf("decode Update: buffer too small for flags")
  1914  	}
  1915  	u.Flags = UpdateFlags(buf[pos])
  1916  	pos++
  1917  	if u.Flags&BalanceUpdate != 0 {
  1918  		if len(buf) < pos+1 {
  1919  			return 0, fmt.Errorf("decode Update: buffer too small for balance len")
  1920  		}
  1921  		balanceLen := int(buf[pos])
  1922  		pos++
  1923  		if len(buf) < pos+balanceLen {
  1924  			return 0, fmt.Errorf("decode Update: buffer too small for balance")
  1925  		}
  1926  		u.Balance.SetBytes(buf[pos : pos+balanceLen])
  1927  		pos += balanceLen
  1928  	}
  1929  	if u.Flags&NonceUpdate != 0 {
  1930  		var n int
  1931  		u.Nonce, n = binary.Uvarint(buf[pos:])
  1932  		if n == 0 {
  1933  			return 0, fmt.Errorf("decode Update: buffer too small for nonce")
  1934  		}
  1935  		if n < 0 {
  1936  			return 0, fmt.Errorf("decode Update: nonce overflow")
  1937  		}
  1938  		pos += n
  1939  	}
  1940  	if u.Flags&CodeUpdate != 0 {
  1941  		if len(buf) < pos+32 {
  1942  			return 0, fmt.Errorf("decode Update: buffer too small for codeHash")
  1943  		}
  1944  		copy(u.CodeHashOrStorage[:], buf[pos:pos+32])
  1945  		pos += 32
  1946  	}
  1947  	if u.Flags&StorageUpdate != 0 {
  1948  		l, n := binary.Uvarint(buf[pos:])
  1949  		if n == 0 {
  1950  			return 0, fmt.Errorf("decode Update: buffer too small for storage len")
  1951  		}
  1952  		if n < 0 {
  1953  			return 0, fmt.Errorf("decode Update: storage lee overflow")
  1954  		}
  1955  		pos += n
  1956  		if len(buf) < pos+int(l) {
  1957  			return 0, fmt.Errorf("decode Update: buffer too small for storage")
  1958  		}
  1959  		u.ValLength = int(l)
  1960  		copy(u.CodeHashOrStorage[:], buf[pos:pos+int(l)])
  1961  		pos += int(l)
  1962  	}
  1963  	return pos, nil
  1964  }
  1965  
  1966  func (u *Update) String() string {
  1967  	var sb strings.Builder
  1968  	sb.WriteString(fmt.Sprintf("Flags: [%s]", u.Flags))
  1969  	if u.Flags&BalanceUpdate != 0 {
  1970  		sb.WriteString(fmt.Sprintf(", Balance: [%d]", &u.Balance))
  1971  	}
  1972  	if u.Flags&NonceUpdate != 0 {
  1973  		sb.WriteString(fmt.Sprintf(", Nonce: [%d]", u.Nonce))
  1974  	}
  1975  	if u.Flags&CodeUpdate != 0 {
  1976  		sb.WriteString(fmt.Sprintf(", CodeHash: [%x]", u.CodeHashOrStorage))
  1977  	}
  1978  	if u.Flags&StorageUpdate != 0 {
  1979  		sb.WriteString(fmt.Sprintf(", Storage: [%x]", u.CodeHashOrStorage[:u.ValLength]))
  1980  	}
  1981  	return sb.String()
  1982  }