@@ -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