@@ -14,30 +14,33 @@ import (
14
14
"github.com/libp2p/go-libp2p/core/peerstore"
15
15
"github.com/libp2p/go-libp2p/core/protocol"
16
16
"github.com/libp2p/go-libp2p/core/record"
17
- "github.com/libp2p/go-libp2p/p2p/host/eventbus"
18
-
19
17
logging "github.com/libp2p/go-libp2p/gologshim"
18
+ "github.com/libp2p/go-libp2p/p2p/host/eventbus"
20
19
21
20
ma "github.com/multiformats/go-multiaddr"
22
21
mstream "github.com/multiformats/go-multistream"
23
22
)
24
23
25
24
var log = logging .Logger ("blankhost" )
26
25
27
- // BlankHost is the thinnest implementation of the host.Host interface
26
+ // BlankHost is a thin implementation of the host.Host interface
28
27
type BlankHost struct {
29
- n network.Network
30
- mux * mstream.MultistreamMuxer [protocol.ID ]
31
- cmgr connmgr.ConnManager
32
- eventbus event.Bus
33
- emitters struct {
28
+ N network.Network
29
+ M * mstream.MultistreamMuxer [protocol.ID ]
30
+ E event.Bus
31
+ ConnMgr connmgr.ConnManager
32
+ // SkipInitSignedRecord is a flag to skip the initialization of a signed record for the host
33
+ SkipInitSignedRecord bool
34
+ emitters struct {
34
35
evtLocalProtocolsUpdated event.Emitter
35
36
}
37
+ onStop []func () error
36
38
}
37
39
38
40
type config struct {
39
- cmgr connmgr.ConnManager
40
- eventBus event.Bus
41
+ cmgr connmgr.ConnManager
42
+ eventBus event.Bus
43
+ skipInitSignedRecord bool
41
44
}
42
45
43
46
type Option = func (cfg * config )
@@ -54,6 +57,12 @@ func WithEventBus(eventBus event.Bus) Option {
54
57
}
55
58
}
56
59
60
+ func SkipInitSignedRecord () Option {
61
+ return func (cfg * config ) {
62
+ cfg .skipInitSignedRecord = true
63
+ }
64
+ }
65
+
57
66
func NewBlankHost (n network.Network , options ... Option ) * BlankHost {
58
67
cfg := config {
59
68
cmgr : & connmgr.NullConnMgr {},
@@ -63,36 +72,72 @@ func NewBlankHost(n network.Network, options ...Option) *BlankHost {
63
72
}
64
73
65
74
bh := & BlankHost {
66
- n : n ,
67
- cmgr : cfg .cmgr ,
68
- mux : mstream .NewMultistreamMuxer [protocol.ID ](),
69
- eventbus : cfg .eventBus ,
75
+ N : n ,
76
+ ConnMgr : cfg .cmgr ,
77
+ M : mstream .NewMultistreamMuxer [protocol.ID ](),
78
+ E : cfg .eventBus ,
79
+
80
+ SkipInitSignedRecord : cfg .skipInitSignedRecord ,
70
81
}
71
- if bh .eventbus == nil {
72
- bh .eventbus = eventbus .NewBus (eventbus .WithMetricsTracer (eventbus .NewMetricsTracer ()))
82
+
83
+ if err := bh .Start (); err != nil {
84
+ log .Error ("error creating blank host" , "err" , err )
85
+ return nil
86
+ }
87
+
88
+ return bh
89
+ }
90
+
91
+ func (bh * BlankHost ) Start () error {
92
+ if bh .E == nil {
93
+ bh .E = eventbus .NewBus (eventbus .WithMetricsTracer (eventbus .NewMetricsTracer ()))
73
94
}
74
95
75
96
// subscribe the connection manager to network notifications (has no effect with NullConnMgr)
76
- n .Notify (bh .cmgr .Notifee ())
97
+ notifee := bh .ConnMgr .Notifee ()
98
+ bh .N .Notify (notifee )
99
+ bh .onStop = append (bh .onStop , func () error {
100
+ bh .N .StopNotify (notifee )
101
+ return nil
102
+ })
77
103
78
104
var err error
79
- if bh .emitters .evtLocalProtocolsUpdated , err = bh .eventbus .Emitter (& event.EvtLocalProtocolsUpdated {}); err != nil {
80
- return nil
105
+ if bh .emitters .evtLocalProtocolsUpdated , err = bh .E .Emitter (& event.EvtLocalProtocolsUpdated {}); err != nil {
106
+ return err
81
107
}
108
+ bh .onStop = append (bh .onStop , func () error {
109
+ bh .emitters .evtLocalProtocolsUpdated .Close ()
110
+ return nil
111
+ })
82
112
83
- n .SetStreamHandler (bh .newStreamHandler )
113
+ bh .N .SetStreamHandler (bh .newStreamHandler )
114
+ bh .onStop = append (bh .onStop , func () error {
115
+ bh .N .SetStreamHandler (func (s network.Stream ) { s .Reset () })
116
+ return nil
117
+ })
84
118
85
119
// persist a signed peer record for self to the peerstore.
86
- if err := bh .initSignedRecord (); err != nil {
87
- log .Error ("error creating blank host" , "err" , err )
88
- return nil
120
+ if ! bh .SkipInitSignedRecord {
121
+ if err := bh .initSignedRecord (); err != nil {
122
+ log .Error ("error creating blank host" , "err" , err )
123
+ return err
124
+ }
89
125
}
90
126
91
- return bh
127
+ return nil
128
+ }
129
+
130
+ func (bh * BlankHost ) Stop () error {
131
+ var err error
132
+ for _ , f := range bh .onStop {
133
+ err = errors .Join (err , f ())
134
+ }
135
+ bh .onStop = nil
136
+ return err
92
137
}
93
138
94
139
func (bh * BlankHost ) initSignedRecord () error {
95
- cab , ok := peerstore .GetCertifiedAddrBook (bh .n .Peerstore ())
140
+ cab , ok := peerstore .GetCertifiedAddrBook (bh .N .Peerstore ())
96
141
if ! ok {
97
142
log .Error ("peerstore does not support signed records" )
98
143
return errors .New ("peerstore does not support signed records" )
@@ -114,7 +159,7 @@ func (bh *BlankHost) initSignedRecord() error {
114
159
var _ host.Host = (* BlankHost )(nil )
115
160
116
161
func (bh * BlankHost ) Addrs () []ma.Multiaddr {
117
- addrs , err := bh .n .InterfaceListenAddresses ()
162
+ addrs , err := bh .N .InterfaceListenAddresses ()
118
163
if err != nil {
119
164
log .Debug ("error retrieving network interface addrs" , "err" , err )
120
165
return nil
@@ -124,14 +169,18 @@ func (bh *BlankHost) Addrs() []ma.Multiaddr {
124
169
}
125
170
126
171
func (bh * BlankHost ) Close () error {
127
- return bh .n .Close ()
172
+ var err error
173
+ if bh .onStop != nil {
174
+ err = bh .Stop ()
175
+ }
176
+ return errors .Join (err , bh .N .Close ())
128
177
}
129
178
130
179
func (bh * BlankHost ) Connect (ctx context.Context , ai peer.AddrInfo ) error {
131
180
// absorb addresses into peerstore
132
181
bh .Peerstore ().AddAddrs (ai .ID , ai .Addrs , peerstore .TempAddrTTL )
133
182
134
- cs := bh .n .ConnsToPeer (ai .ID )
183
+ cs := bh .N .ConnsToPeer (ai .ID )
135
184
if len (cs ) > 0 {
136
185
return nil
137
186
}
@@ -144,15 +193,15 @@ func (bh *BlankHost) Connect(ctx context.Context, ai peer.AddrInfo) error {
144
193
}
145
194
146
195
func (bh * BlankHost ) Peerstore () peerstore.Peerstore {
147
- return bh .n .Peerstore ()
196
+ return bh .N .Peerstore ()
148
197
}
149
198
150
199
func (bh * BlankHost ) ID () peer.ID {
151
- return bh .n .LocalPeer ()
200
+ return bh .N .LocalPeer ()
152
201
}
153
202
154
203
func (bh * BlankHost ) NewStream (ctx context.Context , p peer.ID , protos ... protocol.ID ) (network.Stream , error ) {
155
- s , err := bh .n .NewStream (ctx , p )
204
+ s , err := bh .N .NewStream (ctx , p )
156
205
if err != nil {
157
206
return nil , fmt .Errorf ("failed to open stream: %w" , err )
158
207
}
@@ -204,7 +253,7 @@ func (bh *BlankHost) SetStreamHandlerMatch(pid protocol.ID, m func(protocol.ID)
204
253
func (bh * BlankHost ) newStreamHandler (s network.Stream ) {
205
254
protoID , handle , err := bh .Mux ().Negotiate (s )
206
255
if err != nil {
207
- log .Info ("protocol negotiation failed" , "err" , err )
256
+ log .Error ("protocol negotiation failed" , "err" , err )
208
257
s .Reset ()
209
258
return
210
259
}
@@ -216,18 +265,18 @@ func (bh *BlankHost) newStreamHandler(s network.Stream) {
216
265
217
266
// TODO: i'm not sure this really needs to be here
218
267
func (bh * BlankHost ) Mux () protocol.Switch {
219
- return bh .mux
268
+ return bh .M
220
269
}
221
270
222
271
// TODO: also not sure this fits... Might be better ways around this (leaky abstractions)
223
272
func (bh * BlankHost ) Network () network.Network {
224
- return bh .n
273
+ return bh .N
225
274
}
226
275
227
276
func (bh * BlankHost ) ConnManager () connmgr.ConnManager {
228
- return bh .cmgr
277
+ return bh .ConnMgr
229
278
}
230
279
231
280
func (bh * BlankHost ) EventBus () event.Bus {
232
- return bh .eventbus
281
+ return bh .E
233
282
}
0 commit comments