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

     1  package change
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  
     7  	"github.com/lbryio/lbcd/chaincfg/chainhash"
     8  	"github.com/lbryio/lbcd/wire"
     9  )
    10  
    11  type ChangeType uint32
    12  
    13  const (
    14  	AddClaim ChangeType = iota
    15  	SpendClaim
    16  	UpdateClaim
    17  	AddSupport
    18  	SpendSupport
    19  )
    20  
    21  type Change struct {
    22  	Type   ChangeType
    23  	Height int32
    24  
    25  	Name     []byte
    26  	ClaimID  ClaimID
    27  	OutPoint wire.OutPoint
    28  	Amount   int64
    29  
    30  	ActiveHeight  int32
    31  	VisibleHeight int32 // aka, CreatedAt; used for normalization fork
    32  
    33  	SpentChildren map[string]bool
    34  }
    35  
    36  func NewChange(typ ChangeType) Change {
    37  	return Change{Type: typ}
    38  }
    39  
    40  func (c Change) SetHeight(height int32) Change {
    41  	c.Height = height
    42  	return c
    43  }
    44  
    45  func (c Change) SetName(name []byte) Change {
    46  	c.Name = name // need to clone it?
    47  	return c
    48  }
    49  
    50  func (c Change) SetOutPoint(op *wire.OutPoint) Change {
    51  	c.OutPoint = *op
    52  	return c
    53  }
    54  
    55  func (c Change) SetAmount(amt int64) Change {
    56  	c.Amount = amt
    57  	return c
    58  }
    59  
    60  func (c *Change) Marshal(enc *bytes.Buffer) error {
    61  	enc.Write(c.ClaimID[:])
    62  	enc.Write(c.OutPoint.Hash[:])
    63  	var temp [8]byte
    64  	binary.BigEndian.PutUint32(temp[:4], c.OutPoint.Index)
    65  	enc.Write(temp[:4])
    66  	binary.BigEndian.PutUint32(temp[:4], uint32(c.Type))
    67  	enc.Write(temp[:4])
    68  	binary.BigEndian.PutUint32(temp[:4], uint32(c.Height))
    69  	enc.Write(temp[:4])
    70  	binary.BigEndian.PutUint32(temp[:4], uint32(c.ActiveHeight))
    71  	enc.Write(temp[:4])
    72  	binary.BigEndian.PutUint32(temp[:4], uint32(c.VisibleHeight))
    73  	enc.Write(temp[:4])
    74  	binary.BigEndian.PutUint64(temp[:], uint64(c.Amount))
    75  	enc.Write(temp[:])
    76  
    77  	if c.SpentChildren != nil {
    78  		binary.BigEndian.PutUint32(temp[:4], uint32(len(c.SpentChildren)))
    79  		enc.Write(temp[:4])
    80  		for key := range c.SpentChildren {
    81  			keySize := uint16(len(key))
    82  			binary.BigEndian.PutUint16(temp[:2], keySize) // technically limited to 255; not sure we trust it
    83  			enc.Write(temp[:2])
    84  			enc.WriteString(key[:keySize])
    85  		}
    86  	} else {
    87  		binary.BigEndian.PutUint32(temp[:4], 0)
    88  		enc.Write(temp[:4])
    89  	}
    90  	return nil
    91  }
    92  
    93  func (c *Change) Unmarshal(dec *bytes.Buffer) error {
    94  	copy(c.ClaimID[:], dec.Next(ClaimIDSize))
    95  	copy(c.OutPoint.Hash[:], dec.Next(chainhash.HashSize))
    96  	c.OutPoint.Index = binary.BigEndian.Uint32(dec.Next(4))
    97  	c.Type = ChangeType(binary.BigEndian.Uint32(dec.Next(4)))
    98  	c.Height = int32(binary.BigEndian.Uint32(dec.Next(4)))
    99  	c.ActiveHeight = int32(binary.BigEndian.Uint32(dec.Next(4)))
   100  	c.VisibleHeight = int32(binary.BigEndian.Uint32(dec.Next(4)))
   101  	c.Amount = int64(binary.BigEndian.Uint64(dec.Next(8)))
   102  	keys := binary.BigEndian.Uint32(dec.Next(4))
   103  	if keys > 0 {
   104  		c.SpentChildren = map[string]bool{}
   105  	}
   106  	for keys > 0 {
   107  		keys--
   108  		keySize := int(binary.BigEndian.Uint16(dec.Next(2)))
   109  		key := string(dec.Next(keySize))
   110  		c.SpentChildren[key] = true
   111  	}
   112  	return nil
   113  }