github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/watchtower/watchtower.go (about) 1 package watchtower 2 3 import ( 4 "fmt" 5 "path/filepath" 6 7 "github.com/boltdb/bolt" 8 "github.com/mit-dci/lit/coinparam" 9 "github.com/mit-dci/lit/lnutil" 10 "github.com/mit-dci/lit/uspv" 11 ) 12 13 type Watcher interface { 14 // Links to the blockchain. 15 // Uses the same chainhook interface as the wallit does. But only uses 16 // 2 of the functions: PushTx() and RawBlocks() 17 // Blocks come in from the chainhook, and justice transactions come out. 18 // The uint32 is the cointype, the string is the folder to put all db files. 19 HookLink(string, *coinparam.Params, uspv.ChainHook) error 20 21 // New Channel to watch 22 NewChannel(lnutil.WatchDescMsg) error 23 24 // Update a channel being watched 25 UpdateChannel(lnutil.WatchStateMsg) error 26 27 // Delete a channel being watched 28 DeleteChannel(lnutil.WatchDelMsg) error 29 30 // Later on, allow users to recover channel state from 31 // the data in a watcher. Like if they wipe their ln.db files but 32 // still have their keys. 33 } 34 35 // The main watchtower struct 36 type WatchTower struct { 37 Path string // where the DB goes? needed? 38 39 WatchDB *bolt.DB // single DB with everything in it 40 // much more efficient to have a separate DB for each cointype 41 // ... but that's less anonymous. To get that efficiency; make a bunch of 42 // towers, I guess. 43 44 Accepting bool // true if new channels and sigs are allowed in 45 Watching bool // true if there are txids to watch for 46 47 SyncHeight int32 // last block we've sync'd to. Not needed? 48 49 // map of cointypes to chainhooks 50 Hooks map[uint32]uspv.ChainHook 51 } 52 53 // Hooklink is the connection between the watchtower and the blockchain 54 // Takes in a channel of blocks, and the cointype. Immediately returns 55 // a channel which it will send justice transactions to. 56 func (w *WatchTower) HookLink(dbPath string, param *coinparam.Params, 57 hook uspv.ChainHook) error { 58 59 cointype := param.HDCoinType 60 61 // if the hooks map hasn't been initialized, make it. also open DB 62 if len(w.Hooks) == 0 { 63 w.Hooks = make(map[uint32]uspv.ChainHook) 64 65 towerDBName := filepath.Join(dbPath, "watch.db") 66 err := w.OpenDB(towerDBName) 67 if err != nil { 68 return err 69 } 70 71 } 72 73 // see if this cointype is already registered 74 _, ok := w.Hooks[cointype] 75 if ok { 76 return fmt.Errorf("Coin type %d already linked", cointype) 77 } 78 79 // only need this for the pushTx() method 80 w.Hooks[cointype] = hook 81 82 go w.BlockHandler(cointype, hook.RawBlocks()) 83 84 return nil 85 } 86 87 // 2 structs used in the DB: IdxSigs and ChanStatic 88 89 // IdxSig is what we save in the DB for each txid 90 type IdxSig struct { 91 PKHIdx uint32 // Who 92 StateIdx uint64 // When 93 Sig [64]byte // What 94 } 95 96 /* 97 func (w *WatchTower) HandleMessage(msg lnutil.LitMsg) error { 98 logging.Infof("got message from %x\n", msg.Peer()) 99 100 switch msg.MsgType() { 101 case lnutil.MSGID_WATCH_DESC: 102 logging.Infof("new channel to watch\n") 103 message, ok := msg.(lnutil.WatchDescMsg) 104 if !ok { 105 return fmt.Errorf("didn't work") 106 } else { 107 return w.AddNewChannel(message) 108 } 109 110 case lnutil.MSGID_WATCH_STATEMSG: 111 logging.Infof("new commsg\n") 112 message, ok := msg.(lnutil.WatchStateMsg) 113 if !ok { 114 return fmt.Errorf("didn't work") 115 } else { 116 return w.AddState(message) 117 } 118 119 case lnutil.MSGID_WATCH_DELETE: 120 logging.Infof("delete message\n") 121 // delete not yet implemented 122 default: 123 logging.Infof("unknown message type %x\n", msg.MsgType()) 124 } 125 return nil 126 } 127 */