-
Notifications
You must be signed in to change notification settings - Fork 0
/
neblet.go
187 lines (148 loc) · 3.97 KB
/
neblet.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
package neblet
import (
"errors"
"fmt"
"net"
"sync"
"github.com/multiformats/go-multiaddr"
"github.com/nebulasio/go-nebulas/account"
"github.com/nebulasio/go-nebulas/components/net/p2p"
"github.com/nebulasio/go-nebulas/consensus"
"github.com/nebulasio/go-nebulas/consensus/pow"
"github.com/nebulasio/go-nebulas/core"
"github.com/nebulasio/go-nebulas/neblet/pb"
"github.com/nebulasio/go-nebulas/rpc"
nsync "github.com/nebulasio/go-nebulas/sync"
log "github.com/sirupsen/logrus"
)
var (
// ErrNebletAlreadyRunning throws when the neblet is already running.
ErrNebletAlreadyRunning = errors.New("neblet is already running")
)
// Neblet manages life cycle of blockchain services.
type Neblet struct {
config nebletpb.Config
accountManager *account.Manager
// p2pManager *p2p.Manager
netService *p2p.NetService
consensus consensus.Consensus
blockChain *core.BlockChain
snycManager *nsync.Manager
rpcServer *rpc.Server
lock sync.RWMutex
running bool
}
// New returns a new neblet.
func New(config nebletpb.Config) *Neblet {
return &Neblet{config: config}
}
// Start starts the services of the neblet.
func (n *Neblet) Start() error {
n.lock.Lock()
defer n.lock.Unlock()
log.Info("Starting neblet...")
if n.running {
return ErrNebletAlreadyRunning
}
n.running = true
n.accountManager = account.NewManager(n)
// TODO: use new proto config.
p2pConfig := n.getP2PConfig()
// n.p2pManager = p2p.NewManager(p2pConfig)
n.netService = p2p.NewNetService(p2pConfig)
n.blockChain = core.NewBlockChain(core.TestNetID)
fmt.Printf("chainID is %d\n", n.blockChain.ChainID())
n.blockChain.BlockPool().RegisterInNetwork(n.netService)
n.blockChain.TransactionPool().RegisterInNetwork(n.netService)
n.consensus = pow.NewPow(n)
n.blockChain.SetConsensusHandler(n.consensus)
// start sync service
n.snycManager = nsync.NewManager(n.blockChain, n.consensus, n.netService)
n.rpcServer = rpc.NewServer(n)
// start.
n.netService.Start()
n.blockChain.BlockPool().Start()
n.blockChain.TransactionPool().Start()
n.consensus.Start()
n.snycManager.Start()
go n.rpcServer.Start()
// TODO: error handling
return nil
}
// Stop stops the services of the neblet.
func (n *Neblet) Stop() error {
n.lock.Lock()
defer n.lock.Unlock()
log.Info("Stopping neblet...")
if n.consensus != nil {
n.consensus.Stop()
n.consensus = nil
}
if n.blockChain != nil {
n.blockChain.BlockPool().Stop()
n.blockChain = nil
}
if n.netService != nil {
n.netService.Stop()
n.netService = nil
}
if n.rpcServer != nil {
n.rpcServer.Stop()
n.rpcServer = nil
}
n.accountManager = nil
n.running = false
return nil
}
// Config returns neblet configuration.
func (n *Neblet) Config() nebletpb.Config {
return n.config
}
// BlockChain returns block chain reference.
func (n *Neblet) BlockChain() *core.BlockChain {
return n.blockChain
}
// AccountManager returns account manager reference.
func (n *Neblet) AccountManager() *account.Manager {
return n.accountManager
}
// NetService returns p2p manager reference.
func (n *Neblet) NetService() *p2p.NetService {
return n.netService
}
// TODO: move this to p2p package.
func (n *Neblet) getP2PConfig() *p2p.Config {
config := p2p.DefautConfig()
config.IP = localHost()
seed := n.config.P2P.Seed
if len(seed) > 0 {
seed, err := multiaddr.NewMultiaddr(seed)
if err != nil {
log.Error("param seed error, creating seed node fail", err)
return nil
}
config.BootNodes = []multiaddr.Multiaddr{seed}
}
if port := n.config.P2P.Port; port > 0 {
config.Port = uint(port)
}
// P2P network randseed, in this release we use port as randseed
// config.Randseed = time.Now().Unix()
config.Randseed = int64(config.Port)
return config
}
// TODO: move this to p2p package.
func localHost() string {
addrs, err := net.InterfaceAddrs()
if err != nil {
return ""
}
for _, address := range addrs {
if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
if ipnet.IP.To4() != nil {
return ipnet.IP.String()
}
}
}
return ""
}