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 }