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