@@ -38,63 +38,78 @@ export class DigNetwork {
38
38
storeId : string ,
39
39
rootHash : string ,
40
40
key ?: string ,
41
- intialBlackList : string [ ] = [ ]
41
+ initialBlackList : string [ ] = [ ]
42
42
) : Promise < DigPeer | null > {
43
- const peerBlackList : string [ ] = intialBlackList ;
43
+ const peerBlackList : string [ ] = initialBlackList ;
44
44
const serverCoin = new ServerCoin ( storeId ) ;
45
- let peerIp : string | null = null ;
46
45
47
- // Keep sampling peers until an empty array is returned
48
46
while ( true ) {
49
47
try {
50
- // Sample a peer from the current epoch
51
- const digPeers = await serverCoin . sampleCurrentEpoch ( 1 , peerBlackList ) ;
48
+ // Sample 10 peers from the current epoch
49
+ const digPeers = await serverCoin . sampleCurrentEpoch ( 10 , peerBlackList ) ;
52
50
53
51
// If no peers are returned, break out of the loop
54
52
if ( digPeers . length === 0 ) {
55
53
console . log ( "No more peers found." ) ;
56
54
break ;
57
55
}
58
56
59
- peerIp = digPeers [ 0 ] ;
60
- const digPeer = new DigPeer ( peerIp , storeId ) ;
61
-
62
- // Try to fetch the head store information
63
- const { storeExists, rootHashExists } =
64
- await digPeer . propagationServer . checkStoreExists ( rootHash ) ;
57
+ // Create a race of promises for all peers
58
+ const peerPromises = digPeers . map ( ( peerIp ) => {
59
+ return new Promise < DigPeer | null > ( async ( resolve ) => {
60
+ try {
61
+ const digPeer = new DigPeer ( peerIp , storeId ) ;
62
+ const { storeExists, rootHashExists } =
63
+ await digPeer . propagationServer . checkStoreExists ( rootHash ) ;
64
+
65
+ // Check if the store and root hash exist on the peer
66
+ if ( storeExists && rootHashExists ) {
67
+ console . log (
68
+ `Found Peer at ${ peerIp } for storeId: ${ storeId } , root hash ${ rootHash } `
69
+ ) ;
70
+
71
+ // If no key is provided, resolve the peer
72
+ if ( ! key ) {
73
+ return resolve ( digPeer ) ;
74
+ }
75
+
76
+ // If key is provided, check if the peer has it
77
+ const keyResponse = await digPeer . contentServer . headKey (
78
+ key ,
79
+ rootHash
80
+ ) ;
81
+ if ( keyResponse . headers ?. [ "x-key-exists" ] === "true" ) {
82
+ return resolve ( digPeer ) ;
83
+ }
84
+ }
85
+ } catch ( error ) {
86
+ console . error ( `Error connecting to DIG Peer ${ peerIp } .` ) ;
87
+ }
65
88
66
- // If the peer has the correct root hash, check if key is required
67
- if ( storeExists && rootHashExists ) {
68
- console . log (
69
- `Found Peer at ${ peerIp } for storeId: ${ storeId } , root hash ${ rootHash } `
70
- ) ;
89
+ // If the peer does not meet the criteria, resolve with null
90
+ resolve ( null ) ;
91
+ } ) ;
92
+ } ) ;
71
93
72
- // If no key is provided, return the peer
73
- if ( ! key ) {
74
- return digPeer ;
75
- }
94
+ // Wait for the first valid peer that resolves
95
+ const firstValidPeer = await Promise . race ( peerPromises ) ;
76
96
77
- // If key is provided, check if the peer has it
78
- const keyResponse = await digPeer . contentServer . headKey (
79
- key ,
80
- rootHash
81
- ) ;
82
- if ( keyResponse . headers ?. [ "x-key-exists" ] === "true" ) {
83
- return digPeer ;
84
- }
97
+ // If a valid peer is found, return it
98
+ if ( firstValidPeer ) {
99
+ return firstValidPeer ;
85
100
}
86
101
87
- // Add peer to blacklist if it doesn't meet criteria
88
- peerBlackList . push ( peerIp ) ;
102
+ // If none of the peers were valid, add them to the blacklist
103
+ digPeers . forEach ( ( peerIp ) => peerBlackList . push ( peerIp ) ) ;
104
+
105
+ // Retry with the next set of peers
106
+ console . log ( "No valid peers found, retrying with new peers..." ) ;
89
107
} catch ( error ) {
90
- console . error ( `Error connecting to DIG Peer ${ peerIp } . Resampling...` ) ;
91
- if ( peerIp ) {
92
- peerBlackList . push ( peerIp ) ; // Add to blacklist if error occurs
93
- }
108
+ console . error ( "Error sampling peers. Resampling..." ) ;
94
109
}
95
110
}
96
111
97
- // Return null if no valid peer was found
112
+ // Return null if no valid peer was found after all attempts
98
113
return null ;
99
114
}
100
115
@@ -105,7 +120,10 @@ export class DigNetwork {
105
120
fs . unlinkSync ( path . join ( DIG_FOLDER_PATH , "stores" , storeId + ".json" ) ) ;
106
121
}
107
122
108
- public static async pingNetworkOfUpdate ( storeId : string , rootHash : string ) : Promise < void > {
123
+ public static async pingNetworkOfUpdate (
124
+ storeId : string ,
125
+ rootHash : string
126
+ ) : Promise < void > {
109
127
const serverCoin = new ServerCoin ( storeId ) ;
110
128
// When an update is made, ping 10 network peers to pull updates from this store
111
129
const digPeers = await serverCoin . sampleCurrentEpoch ( 10 ) ;
@@ -115,7 +133,7 @@ export class DigNetwork {
115
133
digPeer . propagationServer . pingUpdate ( rootHash ) ,
116
134
5000 ,
117
135
`headKey timed out for peer ${ digPeer . IpAddress } `
118
- )
136
+ ) ;
119
137
}
120
138
}
121
139
@@ -213,8 +231,11 @@ export class DigNetwork {
213
231
}
214
232
}
215
233
}
216
-
217
- DigNetwork . pingNetworkOfUpdate ( this . dataStore . StoreId , rootInfo . root_hash ) ;
234
+
235
+ DigNetwork . pingNetworkOfUpdate (
236
+ this . dataStore . StoreId ,
237
+ rootInfo . root_hash
238
+ ) ;
218
239
}
219
240
220
241
console . log ( "Syncing store complete." ) ;
0 commit comments