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