github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/qln/serdes.go (about)

     1  package qln
     2  
     3  import (
     4  	"encoding/json"
     5  	"sync"
     6  
     7  	"github.com/mit-dci/lit/elkrem"
     8  	"github.com/mit-dci/lit/portxo"
     9  
    10  	"github.com/getlantern/deepcopy"
    11  )
    12  
    13  /*
    14  note that sigs are truncated and don't have the sighash type byte at the end.
    15  
    16  their rev hash can be derived from the elkrem sender
    17  and the stateidx.  hash160(elkremsend(sIdx)[:16])
    18  
    19  TODO Does it make sense to move this comment somewhere else?  It's not really
    20  relevant here anymore.
    21  */
    22  
    23  // ChanData is a struct used as a surrogate for going between Qchan and the JSON
    24  // representation stored on disk.  There's an annoying layer in between that
    25  // make it all work out with hopefully little friction.
    26  type ChanData struct {
    27  	Txo       portxo.PorTxo `json:"txo"`
    28  	CloseData QCloseData    `json:"closedata"`
    29  
    30  	TheirPub       [33]byte `json:"rpub"`
    31  	TheirRefundPub [33]byte `json:"rrefpub"`
    32  	TheirHAKDBase  [33]byte `json:"rhakdbase"`
    33  
    34  	State *StatCom `json:"state"`
    35  
    36  	LastUpdate uint64 `json:"updateunix"`
    37  }
    38  
    39  // NewQchanFromChanData creates a new qchan from a chandata.
    40  func (nd *LitNode) NewQchanFromChanData(data *ChanData) (*Qchan, error) {
    41  
    42  	sc := new(StatCom)
    43  	deepcopy.Copy(sc, data.State)
    44  
    45  	// I don't know if these errors are supposed to be ignored but that's what
    46  	// other code does so I'm just copying that.
    47  	mp, _ := nd.GetUsePub(data.Txo.KeyGen, UseChannelFund)
    48  	mrp, _ := nd.GetUsePub(data.Txo.KeyGen, UseChannelRefund)
    49  	mhb, _ := nd.GetUsePub(data.Txo.KeyGen, UseChannelHAKDBase)
    50  	elkroot, _ := nd.GetElkremRoot(data.Txo.KeyGen)
    51  
    52  	qc := &Qchan{
    53  		PorTxo:    data.Txo,
    54  		CloseData: data.CloseData,
    55  
    56  		MyPub:          mp,
    57  		TheirPub:       data.TheirPub,
    58  		MyRefundPub:    mrp,
    59  		TheirRefundPub: data.TheirRefundPub,
    60  		MyHAKDBase:     mhb,
    61  		TheirHAKDBase:  data.TheirHAKDBase,
    62  
    63  		ElkSnd: elkrem.NewElkremSender(elkroot),
    64  		ElkRcv: elkrem.NewElkremReceiver(),
    65  
    66  		Delay: 5, // This is defined to just be 5.
    67  
    68  		State: sc,
    69  
    70  		ClearToSend: make(chan bool, 1),
    71  		ChanMtx:     sync.Mutex{},
    72  
    73  		LastUpdate: data.LastUpdate,
    74  	}
    75  
    76  	// I think this might fix the problem?
    77  	go (func() {
    78  		qc.ClearToSend <- true
    79  	})()
    80  
    81  	return qc, nil
    82  
    83  }
    84  
    85  // NewChanDataFromQchan extracts the chandata from the qchan.
    86  func (nd *LitNode) NewChanDataFromQchan(qc *Qchan) *ChanData {
    87  
    88  	// We have to make copies of some thing because it's weird.
    89  	sc := new(StatCom)
    90  	deepcopy.Copy(sc, qc.State)
    91  
    92  	cd := &ChanData{
    93  		Txo:            qc.PorTxo,
    94  		CloseData:      qc.CloseData,
    95  		TheirPub:       qc.TheirPub,
    96  		TheirRefundPub: qc.TheirRefundPub,
    97  		TheirHAKDBase:  qc.TheirHAKDBase,
    98  		State:          sc,
    99  		LastUpdate:     qc.LastUpdate,
   100  	}
   101  
   102  	return cd
   103  
   104  }
   105  
   106  // ApplyChanDataToQchan applies the chandata to the qchan without destroying it.
   107  func (nd *LitNode) ApplyChanDataToQchan(data *ChanData, qc *Qchan) error {
   108  
   109  	fake, err := nd.NewQchanFromChanData(data)
   110  	if err != nil {
   111  		return err
   112  	}
   113  
   114  	// now just copy them over.  this is bad but it should work well enough.
   115  	qc.PorTxo = fake.PorTxo
   116  	qc.CloseData = fake.CloseData
   117  	qc.MyPub = fake.MyPub
   118  	qc.TheirPub = fake.TheirPub
   119  	qc.MyRefundPub = fake.MyRefundPub
   120  	qc.TheirRefundPub = fake.TheirRefundPub
   121  	qc.MyHAKDBase = fake.MyHAKDBase
   122  	qc.TheirHAKDBase = fake.TheirHAKDBase
   123  	qc.WatchRefundAdr = fake.WatchRefundAdr
   124  	qc.ElkSnd = fake.ElkSnd
   125  	qc.ElkRcv = fake.ElkRcv
   126  	qc.Delay = fake.Delay
   127  	qc.State = fake.State
   128  	qc.LastUpdate = fake.LastUpdate
   129  
   130  	return nil
   131  
   132  }
   133  
   134  func (nd *LitNode) QchanSerializeToBytes(qc *Qchan) []byte {
   135  	cd := nd.NewChanDataFromQchan(qc)
   136  	data, _ := json.Marshal(cd)
   137  	return data
   138  }
   139  
   140  func (nd *LitNode) QchanDeserializeFromBytes(buf []byte) (*Qchan, error) {
   141  
   142  	var cd ChanData
   143  	err := json.Unmarshal(buf, &cd)
   144  	if err != nil {
   145  		return nil, err
   146  	}
   147  
   148  	qc, err := nd.NewQchanFromChanData(&cd)
   149  	if err != nil {
   150  		return nil, err
   151  	}
   152  
   153  	return qc, nil
   154  
   155  }
   156  
   157  func (nd *LitNode) QchanUpdateFromBytes(qc *Qchan, buf []byte) error {
   158  
   159  	var err error
   160  	var cd ChanData
   161  	err = json.Unmarshal(buf, &cd)
   162  	if err != nil {
   163  		return err
   164  	}
   165  
   166  	err = nd.ApplyChanDataToQchan(&cd, qc)
   167  	if err != nil {
   168  		return err
   169  	}
   170  
   171  	return nil
   172  
   173  }