|
1 | 1 | package utreexo
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "encoding/hex" |
4 | 5 | "fmt"
|
5 | 6 | "sort"
|
6 | 7 |
|
@@ -54,13 +55,21 @@ func NewAccumulator(full bool) Pollard {
|
54 | 55 | //
|
55 | 56 | // NOTE Modify does NOT do any validation and assumes that all the positions of the leaves
|
56 | 57 | // being deleted have already been verified.
|
57 |
| -func (p *Pollard) Modify(adds []Leaf, delHashes []Hash, dels []uint64) error { |
| 58 | +func (p *Pollard) Modify(adds []Leaf, delHashes []Hash, origDels []uint64) error { |
| 59 | + // Make a copy to avoid mutating the deletion slice passed in. |
| 60 | + delCount := len(origDels) |
| 61 | + dels := make([]uint64, delCount) |
| 62 | + copy(dels, origDels) |
| 63 | + |
| 64 | + // Remove the delHashes from the map. |
58 | 65 | p.deleteFromMap(delHashes)
|
| 66 | + |
| 67 | + // Perform the deletion. It's important that this must happen before the addition. |
59 | 68 | err := p.remove(dels)
|
60 | 69 | if err != nil {
|
61 | 70 | return err
|
62 | 71 | }
|
63 |
| - p.numDels += uint64(len(dels)) |
| 72 | + p.numDels += uint64(delCount) |
64 | 73 |
|
65 | 74 | p.add(adds)
|
66 | 75 |
|
@@ -316,11 +325,17 @@ func (p *Pollard) Undo(numAdds uint64, dels []uint64, delHashes []Hash) error {
|
316 | 325 |
|
317 | 326 | // undoEmptyRoots places empty roots back in after undoing the additions.
|
318 | 327 | func (p *Pollard) undoEmptyRoots(numAdds uint64, origDels []uint64) error {
|
| 328 | + if len(p.roots) >= int(numRoots(p.numLeaves)) { |
| 329 | + return nil |
| 330 | + } |
319 | 331 | dels := make([]uint64, len(origDels))
|
320 | 332 | copy(dels, origDels)
|
321 | 333 |
|
| 334 | + // Sort before detwining. |
| 335 | + slices.Sort(dels) |
322 | 336 | dels = deTwin(dels, treeRows(p.numLeaves))
|
323 |
| - for _, del := range dels { |
| 337 | + for i := len(dels) - 1; i >= 0; i-- { |
| 338 | + del := dels[i] |
324 | 339 | if isRootPosition(del, p.numLeaves, treeRows(p.numLeaves)) {
|
325 | 340 | tree, _, _, err := detectOffset(del, p.numLeaves)
|
326 | 341 | if err != nil {
|
@@ -370,7 +385,7 @@ func (p *Pollard) undoSingleAdd() {
|
370 | 385 |
|
371 | 386 | func (p *Pollard) undoDels(dels []uint64, delHashes []Hash) error {
|
372 | 387 | if len(dels) != len(delHashes) {
|
373 |
| - return fmt.Errorf("Got %d dels but %d delHashes", |
| 388 | + return fmt.Errorf("Got %d targets to be deleted but have %d hashes", |
374 | 389 | len(dels), len(delHashes))
|
375 | 390 | }
|
376 | 391 |
|
@@ -416,7 +431,8 @@ func (p *Pollard) undoSingleDel(node *polNode, pos uint64) error {
|
416 | 431 | siblingPos := parent(pos, totalRows)
|
417 | 432 | sibling, aunt, _, err := p.getNode(siblingPos)
|
418 | 433 | if err != nil {
|
419 |
| - return err |
| 434 | + return fmt.Errorf("Couldn't undo %s at position %d, err: %v", |
| 435 | + hex.EncodeToString(node.data[:]), pos, err) |
420 | 436 | }
|
421 | 437 |
|
422 | 438 | pHash := calculateParentHash(pos, node, sibling)
|
|
0 commit comments