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 }