@@ -44,12 +44,35 @@ export interface AddressFilter {
44
44
45
45
const defaultAddressFilter = ( addrs : Multiaddr [ ] ) : Multiaddr [ ] => addrs
46
46
47
+ interface ObservedAddressMetadata {
48
+ confident : boolean
49
+ }
50
+
51
+ /**
52
+ * If the passed multiaddr contains the passed peer id, remove it
53
+ */
54
+ function stripPeerId ( ma : Multiaddr , peerId : PeerId ) : Multiaddr {
55
+ const observedPeerIdStr = ma . getPeerId ( )
56
+
57
+ // strip our peer id if it has been passed
58
+ if ( observedPeerIdStr != null ) {
59
+ const observedPeerId = peerIdFromString ( observedPeerIdStr )
60
+
61
+ // use same encoding for comparison
62
+ if ( observedPeerId . equals ( peerId ) ) {
63
+ ma = ma . decapsulate ( multiaddr ( `/p2p/${ peerId . toString ( ) } ` ) )
64
+ }
65
+ }
66
+
67
+ return ma
68
+ }
69
+
47
70
export class DefaultAddressManager extends EventEmitter < AddressManagerEvents > {
48
71
private readonly components : DefaultAddressManagerComponents
49
72
// this is an array to allow for duplicates, e.g. multiples of `/ip4/0.0.0.0/tcp/0`
50
73
private readonly listen : string [ ]
51
74
private readonly announce : Set < string >
52
- private readonly observed : Set < string >
75
+ private readonly observed : Map < string , ObservedAddressMetadata >
53
76
private readonly announceFilter : AddressFilter
54
77
55
78
/**
@@ -66,7 +89,7 @@ export class DefaultAddressManager extends EventEmitter<AddressManagerEvents> {
66
89
this . components = components
67
90
this . listen = listen . map ( ma => ma . toString ( ) )
68
91
this . announce = new Set ( announce . map ( ma => ma . toString ( ) ) )
69
- this . observed = new Set ( )
92
+ this . observed = new Map ( )
70
93
this . announceFilter = init . announceFilter ?? defaultAddressFilter
71
94
}
72
95
@@ -88,52 +111,51 @@ export class DefaultAddressManager extends EventEmitter<AddressManagerEvents> {
88
111
* Get observed multiaddrs
89
112
*/
90
113
getObservedAddrs ( ) : Multiaddr [ ] {
91
- return Array . from ( this . observed ) . map ( ( a ) => multiaddr ( a ) )
114
+ return Array . from ( this . observed ) . map ( ( [ a ] ) => multiaddr ( a ) )
92
115
}
93
116
94
117
/**
95
118
* Add peer observed addresses
96
- * Signal that we have confidence an observed multiaddr is publicly dialable -
97
- * this will make it appear in the output of getAddresses()
98
119
*/
99
- confirmObservedAddr ( addr : Multiaddr ) : void {
100
-
101
- }
120
+ addObservedAddr ( addr : Multiaddr ) : void {
121
+ addr = stripPeerId ( addr , this . components . peerId )
122
+ const addrString = addr . toString ( )
102
123
103
- /**
104
- * Signal that we do not have confidence an observed multiaddr is publicly dialable -
105
- * this will remove it from the output of getObservedAddrs()
106
- */
107
- removeObservedAddr ( addr : Multiaddr ) : void {
124
+ // do not trigger the change:addresses event if we already know about this address
125
+ if ( this . observed . has ( addrString ) ) {
126
+ return
127
+ }
108
128
129
+ this . observed . set ( addrString , {
130
+ confident : false
131
+ } )
109
132
}
110
133
111
- /**
112
- * Add peer observed addresses
113
- */
114
- addObservedAddr ( addr : string | Multiaddr ) : void {
115
- let ma = multiaddr ( addr )
116
- const remotePeer = ma . getPeerId ( )
117
-
118
- // strip our peer id if it has been passed
119
- if ( remotePeer != null ) {
120
- const remotePeerId = peerIdFromString ( remotePeer )
121
-
122
- // use same encoding for comparison
123
- if ( remotePeerId . equals ( this . components . peerId ) ) {
124
- ma = ma . decapsulate ( multiaddr ( `/p2p/${ this . components . peerId . toString ( ) } ` ) )
125
- }
134
+ confirmObservedAddr ( addr : Multiaddr ) : void {
135
+ addr = stripPeerId ( addr , this . components . peerId )
136
+ const addrString = addr . toString ( )
137
+
138
+ const metadata = this . observed . get ( addrString ) ?? {
139
+ confident : false
126
140
}
127
141
128
- const addrString = ma . toString ( )
142
+ const startingConfidence = metadata . confident
129
143
130
- // do not trigger the change:addresses event if we already know about this address
131
- if ( this . observed . has ( addrString ) ) {
132
- return
144
+ this . observed . set ( addrString , {
145
+ confident : true
146
+ } )
147
+
148
+ // only trigger the change:addresses event if our confidence in an address has changed
149
+ if ( ! startingConfidence ) {
150
+ this . dispatchEvent ( new CustomEvent ( 'change:addresses' ) )
133
151
}
152
+ }
153
+
154
+ removeObservedAddr ( addr : Multiaddr ) : void {
155
+ addr = stripPeerId ( addr , this . components . peerId )
156
+ const addrString = addr . toString ( )
134
157
135
- this . observed . add ( addrString )
136
- this . dispatchEvent ( new CustomEvent ( 'change:addresses' ) )
158
+ this . observed . delete ( addrString )
137
159
}
138
160
139
161
getAddresses ( ) : Multiaddr [ ] {
@@ -144,7 +166,12 @@ export class DefaultAddressManager extends EventEmitter<AddressManagerEvents> {
144
166
addrs = this . components . transportManager . getAddrs ( ) . map ( ma => ma . toString ( ) )
145
167
}
146
168
147
- addrs = addrs . concat ( this . getObservedAddrs ( ) . map ( ma => ma . toString ( ) ) )
169
+ // add observed addresses we are confident in
170
+ addrs = addrs . concat (
171
+ Array . from ( this . observed )
172
+ . filter ( ( [ ma , metadata ] ) => metadata . confident )
173
+ . map ( ( [ ma ] ) => ma )
174
+ )
148
175
149
176
// dedupe multiaddrs
150
177
const addrSet = new Set ( addrs )
0 commit comments