forked from mit-dci/lit
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlit.go
212 lines (168 loc) · 5.45 KB
/
lit.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
package main
import (
"flag"
"fmt"
"io"
"log"
"os"
"path/filepath"
"strings"
"time"
"github.com/adiabat/btcd/chaincfg"
"github.com/mit-dci/lit/litbamf"
"github.com/mit-dci/lit/litrpc"
"github.com/mit-dci/lit/lnutil"
"github.com/mit-dci/lit/qln"
)
const (
litHomeDirName = ".lit"
keyFileName = "privkey.hex"
// this is my local testnet node, replace it with your own close by.
// Random internet testnet nodes usually work but sometimes don't, so
// maybe I should test against different versions out there.
hardHeight = 1111111 // height to start at if not specified
)
// variables for a lit node & lower layers
type LitConfig struct {
reSync, hard bool // flag to set networks
// hostnames to connect to for different networks
tn3host, bc2host, lt4host, reghost, litereghost string
verbose bool
birthblock int32
rpcport uint16
litHomeDir string
Params *chaincfg.Params
}
func setConfig(lc *LitConfig) {
birthptr := flag.Int("tip", hardHeight, "height to begin db sync")
easyptr := flag.Bool("ez", false, "use easy mode (bloom filters)")
verbptr := flag.Bool("v", false, "verbose; print all logs to stdout")
tn3ptr := flag.String("tn3", "testnet3.lit3.co", "testnet3 full node")
regptr := flag.String("reg", "", "regtest full node")
literegptr := flag.String("ltr", "", "litecoin regtest full node")
bc2ptr := flag.String("bc2", "", "bc2 full node")
lt4ptr := flag.String("lt4", "litetest4.lit3.co", "litecoin testnet4 full node")
resyncprt := flag.Bool("resync", false, "force resync from given tip")
rpcportptr := flag.Int("rpcport", 8001, "port to listen for RPC")
litHomeDir := flag.String("dir",
filepath.Join(os.Getenv("HOME"), litHomeDirName), "lit home directory")
flag.Parse()
lc.birthblock = int32(*birthptr)
lc.tn3host, lc.bc2host, lc.lt4host, lc.reghost =
*tn3ptr, *bc2ptr, *lt4ptr, *regptr
lc.litereghost = *literegptr
lc.reSync = *resyncprt
lc.hard = !*easyptr
lc.verbose = *verbptr
lc.rpcport = uint16(*rpcportptr)
lc.litHomeDir = *litHomeDir
}
// linkWallets tries to link the wallets given in conf to the litNode
func linkWallets(node *qln.LitNode, key *[32]byte, conf *LitConfig) error {
// for now, wallets are linked to the litnode on startup, and
// can't appear / disappear while it's running. Later
// could support dynamically adding / removing wallets
// order matters; the first registered wallet becomes the default
var err error
// try regtest
if conf.reghost != "" {
p := &chaincfg.RegressionNetParams
if !strings.Contains(conf.reghost, ":") {
conf.reghost = conf.reghost + ":" + p.DefaultPort
}
fmt.Printf("reg: %s\n", conf.reghost)
err = node.LinkBaseWallet(key, 120, conf.reSync, conf.reghost, p)
if err != nil {
return err
}
}
// try testnet3
if conf.tn3host != "" {
p := &chaincfg.TestNet3Params
if !strings.Contains(conf.tn3host, ":") {
conf.tn3host = conf.tn3host + ":" + p.DefaultPort
}
err = node.LinkBaseWallet(
key, conf.birthblock, conf.reSync, conf.tn3host, p)
if err != nil {
return err
}
}
// try litecoin regtest
if conf.litereghost != "" {
p := &chaincfg.LiteRegNetParams
if !strings.Contains(conf.litereghost, ":") {
conf.litereghost = conf.litereghost + ":" + p.DefaultPort
}
err = node.LinkBaseWallet(key, 120, conf.reSync, conf.litereghost, p)
if err != nil {
return err
}
}
// try litecoin testnet4
if conf.lt4host != "" {
p := &chaincfg.LiteCoinTestNet4Params
if !strings.Contains(conf.lt4host, ":") {
conf.lt4host = conf.lt4host + ":" + p.DefaultPort
}
err = node.LinkBaseWallet(key, 47295, conf.reSync, conf.lt4host, p)
if err != nil {
return err
}
}
return nil
}
func main() {
log.Printf("lit v0.1\n")
log.Printf("-h for list of options.\n")
conf := new(LitConfig)
setConfig(conf)
// create lit home directory if the diretory does not exist
if _, err := os.Stat(conf.litHomeDir); os.IsNotExist(err) {
os.Mkdir(conf.litHomeDir, 0700)
}
logFilePath := filepath.Join(conf.litHomeDir, "lit.log")
logfile, err := os.OpenFile(logFilePath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
defer logfile.Close()
log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds)
if conf.verbose {
logOutput := io.MultiWriter(os.Stdout, logfile)
log.SetOutput(logOutput)
} else {
log.SetOutput(logfile)
}
// Allow node with no linked wallets, for testing.
// TODO Should update tests and disallow nodes without wallets later.
// if conf.tn3host == "" && conf.lt4host == "" && conf.reghost == "" {
// log.Fatal("error: no network specified; use -tn3, -reg, -lt4")
// }
// Keys: the litNode, and wallits, all get 32 byte keys.
// Right now though, they all get the *same* key. For lit as a single binary
// now, all using the same key makes sense; could split up later.
keyFilePath := filepath.Join(conf.litHomeDir, keyFileName)
// read key file (generate if not found)
key, err := lnutil.ReadKeyFile(keyFilePath)
if err != nil {
log.Fatal(err)
}
// Setup LN node. Activate Tower if in hard mode.
// give node and below file pathof lit home directoy
node, err := qln.NewLitNode(key, conf.litHomeDir, false)
if err != nil {
log.Fatal(err)
}
// node is up; link wallets based on args
err = linkWallets(node, key, conf)
if err != nil {
log.Fatal(err)
}
rpcl := new(litrpc.LitRPC)
rpcl.Node = node
rpcl.OffButton = make(chan bool, 1)
litrpc.RPCListen(rpcl, conf.rpcport)
litbamf.BamfListen(conf.rpcport, conf.litHomeDir)
<-rpcl.OffButton
fmt.Printf("Got stop request\n")
time.Sleep(time.Second)
return
}