github.com/lbryio/lbcd@v0.22.119/claimtrie/node/normalizing_manager.go (about)

     1  package node
     2  
     3  import (
     4  	"bytes"
     5  
     6  	"github.com/lbryio/lbcd/claimtrie/change"
     7  	"github.com/lbryio/lbcd/claimtrie/normalization"
     8  	"github.com/lbryio/lbcd/claimtrie/param"
     9  )
    10  
    11  type NormalizingManager struct { // implements Manager
    12  	Manager
    13  	normalizedAt int32
    14  }
    15  
    16  func NewNormalizingManager(baseManager Manager) Manager {
    17  	log.Info(normalization.NormalizeTitle)
    18  	return &NormalizingManager{
    19  		Manager:      baseManager,
    20  		normalizedAt: -1,
    21  	}
    22  }
    23  
    24  func (nm *NormalizingManager) AppendChange(chg change.Change) {
    25  	chg.Name = normalization.NormalizeIfNecessary(chg.Name, chg.Height)
    26  	nm.Manager.AppendChange(chg)
    27  }
    28  
    29  func (nm *NormalizingManager) IncrementHeightTo(height int32, temporary bool) ([][]byte, error) {
    30  	nm.addNormalizationForkChangesIfNecessary(height)
    31  	return nm.Manager.IncrementHeightTo(height, temporary)
    32  }
    33  
    34  func (nm *NormalizingManager) DecrementHeightTo(affectedNames [][]byte, height int32) ([][]byte, error) {
    35  	if nm.normalizedAt > height {
    36  		nm.normalizedAt = -1
    37  		nm.ClearCache()
    38  	}
    39  	return nm.Manager.DecrementHeightTo(affectedNames, height)
    40  }
    41  
    42  func (nm *NormalizingManager) addNormalizationForkChangesIfNecessary(height int32) {
    43  
    44  	if nm.Manager.Height()+1 != height {
    45  		// initialization phase
    46  		if height >= param.ActiveParams.NormalizedNameForkHeight {
    47  			nm.normalizedAt = param.ActiveParams.NormalizedNameForkHeight // eh, we don't really know that it happened there
    48  		}
    49  	}
    50  
    51  	if nm.normalizedAt >= 0 || height != param.ActiveParams.NormalizedNameForkHeight {
    52  		return
    53  	}
    54  	nm.normalizedAt = height
    55  	log.Info("Generating necessary changes for the normalization fork...")
    56  
    57  	// the original code had an unfortunate bug where many unnecessary takeovers
    58  	// were triggered at the normalization fork
    59  	predicate := func(name []byte) bool {
    60  		norm := normalization.Normalize(name)
    61  		eq := bytes.Equal(name, norm)
    62  		if eq {
    63  			return true
    64  		}
    65  
    66  		clone := make([]byte, len(name))
    67  		copy(clone, name) // iteration name buffer is reused on future loops
    68  
    69  		// by loading changes for norm here, you can determine if there will be a conflict
    70  
    71  		n, err := nm.Manager.NodeAt(nm.Manager.Height(), clone)
    72  		if err != nil || n == nil {
    73  			return true
    74  		}
    75  		for _, c := range n.Claims {
    76  			nm.Manager.AppendChange(change.Change{
    77  				Type:          change.AddClaim,
    78  				Name:          norm,
    79  				Height:        c.AcceptedAt,
    80  				OutPoint:      c.OutPoint,
    81  				ClaimID:       c.ClaimID,
    82  				Amount:        c.Amount,
    83  				ActiveHeight:  c.ActiveAt, // necessary to match the old hash
    84  				VisibleHeight: height,     // necessary to match the old hash; it would have been much better without
    85  			})
    86  			nm.Manager.AppendChange(change.Change{
    87  				Type:     change.SpendClaim,
    88  				Name:     clone,
    89  				Height:   height,
    90  				OutPoint: c.OutPoint,
    91  			})
    92  		}
    93  		for _, c := range n.Supports {
    94  			nm.Manager.AppendChange(change.Change{
    95  				Type:          change.AddSupport,
    96  				Name:          norm,
    97  				Height:        c.AcceptedAt,
    98  				OutPoint:      c.OutPoint,
    99  				ClaimID:       c.ClaimID,
   100  				Amount:        c.Amount,
   101  				ActiveHeight:  c.ActiveAt,
   102  				VisibleHeight: height,
   103  			})
   104  			nm.Manager.AppendChange(change.Change{
   105  				Type:     change.SpendSupport,
   106  				Name:     clone,
   107  				Height:   height,
   108  				OutPoint: c.OutPoint,
   109  			})
   110  		}
   111  
   112  		return true
   113  	}
   114  
   115  	nm.Manager.ClearCache()
   116  	nm.Manager.IterateNames(predicate)
   117  }