-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
exchange signed routing records in identify #747
Changes from 41 commits
94439e6
cfd7149
daaef63
2db11a5
c999bd0
b632eba
8948610
c97dd74
de97dd1
2b0a74e
c2309af
3f7951d
71187c5
baf71df
f86b996
5fc5ead
c86f6e3
ad52da5
63c99a2
ea966e2
64f1353
6ecbfea
1f922f0
58fe062
c019ac1
1da3bd5
8d316c3
ba8f960
db2625b
839c8d2
aff832d
140feb8
c775624
0808676
65c2cf1
4bfae9d
a45bb3f
6fa7285
4269886
ffef2df
c351c42
d740574
4474645
15310dc
3b2ae0a
8c60995
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,28 +2,31 @@ package basichost | |
|
||
import ( | ||
"context" | ||
"errors" | ||
"io" | ||
"net" | ||
"time" | ||
|
||
"github.com/libp2p/go-libp2p/p2p/protocol/identify" | ||
"github.com/libp2p/go-libp2p/p2p/protocol/ping" | ||
|
||
"github.com/libp2p/go-libp2p-core/connmgr" | ||
"github.com/libp2p/go-libp2p-core/crypto" | ||
"github.com/libp2p/go-libp2p-core/event" | ||
"github.com/libp2p/go-libp2p-core/host" | ||
"github.com/libp2p/go-libp2p-core/network" | ||
"github.com/libp2p/go-libp2p-core/peer" | ||
"github.com/libp2p/go-libp2p-core/peerstore" | ||
"github.com/libp2p/go-libp2p-core/protocol" | ||
"github.com/libp2p/go-libp2p-core/record" | ||
|
||
"github.com/libp2p/go-eventbus" | ||
inat "github.com/libp2p/go-libp2p-nat" | ||
"github.com/libp2p/go-libp2p/p2p/protocol/identify" | ||
"github.com/libp2p/go-libp2p/p2p/protocol/ping" | ||
|
||
logging "github.com/ipfs/go-log" | ||
"github.com/jbenet/goprocess" | ||
goprocessctx "github.com/jbenet/goprocess/context" | ||
|
||
"github.com/multiformats/go-multiaddr" | ||
ma "github.com/multiformats/go-multiaddr" | ||
madns "github.com/multiformats/go-multiaddr-dns" | ||
manet "github.com/multiformats/go-multiaddr-net" | ||
|
@@ -89,6 +92,9 @@ type BasicHost struct { | |
} | ||
|
||
addrChangeChan chan struct{} | ||
|
||
signKey crypto.PrivKey | ||
caBook peerstore.CertifiedAddrBook | ||
} | ||
|
||
var _ host.Host = (*BasicHost)(nil) | ||
|
@@ -142,10 +148,21 @@ func NewHost(ctx context.Context, net network.Network, opts *HostOpts) (*BasicHo | |
if h.emitters.evtLocalProtocolsUpdated, err = h.eventbus.Emitter(&event.EvtLocalProtocolsUpdated{}); err != nil { | ||
return nil, err | ||
} | ||
if h.emitters.evtLocalAddrsUpdated, err = h.eventbus.Emitter(&event.EvtLocalAddressesUpdated{}); err != nil { | ||
if h.emitters.evtLocalAddrsUpdated, err = h.eventbus.Emitter(&event.EvtLocalAddressesUpdated{}, eventbus.Stateful); err != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure if this should be stateful. Are we doing this to get around the fact that we don't have some form of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Stebalien We have a However, calling that when you get a This avoids that race. |
||
return nil, err | ||
} | ||
|
||
cab, ok := peerstore.GetCertifiedAddrBook(net.Peerstore()) | ||
if !ok { | ||
return nil, errors.New("peerstore should also be a certified address book") | ||
} | ||
h.caBook = cab | ||
|
||
h.signKey = h.Peerstore().PrivKey(h.ID()) | ||
if h.signKey == nil { | ||
return nil, errors.New("unable to access host key") | ||
} | ||
|
||
h.proc = goprocessctx.WithContextAndTeardown(ctx, func() error { | ||
if h.natmgr != nil { | ||
h.natmgr.Close() | ||
|
@@ -230,12 +247,12 @@ func New(net network.Network, opts ...interface{}) *BasicHost { | |
} | ||
|
||
h, err := NewHost(context.Background(), net, hostopts) | ||
h.Start() | ||
if err != nil { | ||
// this cannot happen with legacy options | ||
// plus we want to keep the (deprecated) legacy interface unchanged | ||
panic(err) | ||
} | ||
h.Start() | ||
|
||
return h | ||
} | ||
|
@@ -343,15 +360,65 @@ func makeUpdatedAddrEvent(prev, current []ma.Multiaddr) *event.EvtLocalAddresses | |
return &evt | ||
} | ||
|
||
func (h *BasicHost) makeSignedPeerRecord(evt *event.EvtLocalAddressesUpdated) (*record.Envelope, error) { | ||
current := make([]multiaddr.Multiaddr, len(evt.Current)) | ||
Stebalien marked this conversation as resolved.
Show resolved
Hide resolved
|
||
for _, a := range evt.Current { | ||
current = append(current, a.Address) | ||
} | ||
|
||
addrs := make([]multiaddr.Multiaddr, 0, len(current)) | ||
for _, a := range current { | ||
if a == nil { | ||
continue | ||
} | ||
addrs = append(addrs, a) | ||
} | ||
Stebalien marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
rec := peer.NewPeerRecord() | ||
rec.PeerID = h.network.LocalPeer() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. host.ID() There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
rec.Addrs = addrs | ||
Stebalien marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return record.Seal(rec, h.signKey) | ||
} | ||
|
||
func (h *BasicHost) background(p goprocess.Process) { | ||
var lastAddrs []ma.Multiaddr | ||
|
||
emitAddrChange := func(currentAddrs []ma.Multiaddr) { | ||
changeEvt := makeUpdatedAddrEvent(lastAddrs, currentAddrs) | ||
if changeEvt != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Negate the condition to short-circuit instead, and outdent the block. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
// add signed peer record to the event | ||
sr, err := h.makeSignedPeerRecord(changeEvt) | ||
if err != nil { | ||
log.Errorf("error creating a signed peer record from the set of current addresses, err=%s", err) | ||
return | ||
} | ||
changeEvt.SignedPeerRecord = *sr | ||
|
||
// persist the signed record to the peerstore | ||
if _, err := h.caBook.ConsumePeerRecord(sr, peerstore.PermanentAddrTTL); err != nil { | ||
log.Errorf("failed to persist signed peer record in peer store, err=%s", err) | ||
return | ||
} | ||
|
||
// emit addr change event on the bus | ||
if err := h.emitters.evtLocalAddrsUpdated.Emit(*changeEvt); err != nil { | ||
log.Warnf("error emitting event for updated addrs: %s", err) | ||
} | ||
} | ||
} | ||
|
||
// immediately emit the first address change event if we have a listen address | ||
if h.Addrs() != nil { | ||
emitAddrChange(h.Addrs()) | ||
} | ||
// init lastAddrs | ||
lastAddrs = h.Addrs() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is racy. Capture the addresses and use them when emitting the event and setting There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @raulk Even though this code is executed in a single dedicated go-routine, have refactored this to make it easier to reason about. |
||
|
||
// periodically schedules an IdentifyPush to update our peers for changes | ||
// in our address set (if needed) | ||
ticker := time.NewTicker(10 * time.Second) | ||
defer ticker.Stop() | ||
|
||
// initialize lastAddrs | ||
lastAddrs := h.Addrs() | ||
|
||
for { | ||
select { | ||
case <-ticker.C: | ||
|
@@ -360,20 +427,10 @@ func (h *BasicHost) background(p goprocess.Process) { | |
return | ||
} | ||
|
||
// emit an EvtLocalAddressesUpdatedEvent & a Push Identify if our listen addresses have changed. | ||
addrs := h.Addrs() | ||
changeEvt := makeUpdatedAddrEvent(lastAddrs, addrs) | ||
if changeEvt != nil { | ||
lastAddrs = addrs | ||
} | ||
|
||
if changeEvt != nil { | ||
err := h.emitters.evtLocalAddrsUpdated.Emit(*changeEvt) | ||
if err != nil { | ||
log.Warnf("error emitting event for updated addrs: %s", err) | ||
} | ||
h.ids.Push() | ||
} | ||
// emit an EvtLocalAddressesUpdatedEvent event if our listen addresses have changed. | ||
emitAddrChange(h.Addrs()) | ||
// update last seen addrs | ||
lastAddrs = h.Addrs() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Racy. Capture, emit and set. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this bump?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, we do not. This was the remanent of a previous eventbus change I made that we do not need anymore.
This has been fixed.