2
2
// SPDX-License-Identifier: Apache-2.0
3
3
4
4
use bip39:: Mnemonic ;
5
- use std:: collections:: HashMap ;
6
5
use std:: sync:: Arc ;
6
+ use std:: { collections:: HashMap , sync:: Mutex } ;
7
7
use thegraph_core:: { Address , ChainId } ;
8
- use tokio:: {
9
- select,
10
- sync:: {
11
- watch:: { self , Receiver } ,
12
- Mutex ,
13
- } ,
14
- } ;
8
+ use tokio:: sync:: watch:: Receiver ;
15
9
use tracing:: warn;
16
10
17
- use crate :: prelude:: { Allocation , AttestationSigner } ;
11
+ use crate :: {
12
+ prelude:: { Allocation , AttestationSigner } ,
13
+ watcher:: join_and_map_watcher,
14
+ } ;
18
15
19
16
/// An always up-to-date list of attestation signers, one for each of the indexer's allocations.
20
- pub async fn attestation_signers (
21
- mut indexer_allocations_rx : Receiver < HashMap < Address , Allocation > > ,
17
+ pub fn attestation_signers (
18
+ indexer_allocations_rx : Receiver < HashMap < Address , Allocation > > ,
22
19
indexer_mnemonic : Mnemonic ,
23
20
chain_id : ChainId ,
24
- mut dispute_manager_rx : Receiver < Option < Address > > ,
21
+ dispute_manager_rx : Receiver < Address > ,
25
22
) -> Receiver < HashMap < Address , AttestationSigner > > {
26
23
let attestation_signers_map: & ' static Mutex < HashMap < Address , AttestationSigner > > =
27
24
Box :: leak ( Box :: new ( Mutex :: new ( HashMap :: new ( ) ) ) ) ;
28
- let indexer_mnemonic = indexer_mnemonic. to_string ( ) ;
25
+ let indexer_mnemonic = Arc :: new ( indexer_mnemonic. to_string ( ) ) ;
29
26
30
- let starter_signers_map = modify_sigers (
31
- Arc :: new ( indexer_mnemonic. clone ( ) ) ,
32
- chain_id,
33
- attestation_signers_map,
34
- indexer_allocations_rx. clone ( ) ,
35
- dispute_manager_rx. clone ( ) ,
27
+ join_and_map_watcher (
28
+ indexer_allocations_rx,
29
+ dispute_manager_rx,
30
+ move |( allocation, dispute) | {
31
+ let indexer_mnemonic = indexer_mnemonic. clone ( ) ;
32
+ modify_sigers (
33
+ & indexer_mnemonic,
34
+ chain_id,
35
+ attestation_signers_map,
36
+ & allocation,
37
+ & dispute,
38
+ )
39
+ } ,
36
40
)
37
- . await ;
38
-
39
- // Whenever the indexer's active or recently closed allocations change, make sure
40
- // we have attestation signers for all of them.
41
- let ( signers_tx, signers_rx) = watch:: channel ( starter_signers_map) ;
42
- tokio:: spawn ( async move {
43
- loop {
44
- let updated_signers = select ! {
45
- Ok ( ( ) ) = indexer_allocations_rx. changed( ) =>{
46
- modify_sigers(
47
- Arc :: new( indexer_mnemonic. clone( ) ) ,
48
- chain_id,
49
- attestation_signers_map,
50
- indexer_allocations_rx. clone( ) ,
51
- dispute_manager_rx. clone( ) ,
52
- ) . await
53
- } ,
54
- Ok ( ( ) ) = dispute_manager_rx. changed( ) =>{
55
- modify_sigers(
56
- Arc :: new( indexer_mnemonic. clone( ) ) ,
57
- chain_id,
58
- attestation_signers_map,
59
- indexer_allocations_rx. clone( ) ,
60
- dispute_manager_rx. clone( )
61
- ) . await
62
- } ,
63
- else=>{
64
- // Something is wrong.
65
- panic!( "dispute_manager_rx or allocations_rx was dropped" ) ;
66
- }
67
- } ;
68
- signers_tx
69
- . send ( updated_signers)
70
- . expect ( "Failed to update signers channel" ) ;
71
- }
72
- } ) ;
73
-
74
- signers_rx
75
41
}
76
- async fn modify_sigers (
77
- indexer_mnemonic : Arc < String > ,
42
+ fn modify_sigers (
43
+ indexer_mnemonic : & str ,
78
44
chain_id : ChainId ,
79
45
attestation_signers_map : & ' static Mutex < HashMap < Address , AttestationSigner > > ,
80
- allocations_rx : Receiver < HashMap < Address , Allocation > > ,
81
- dispute_manager_rx : Receiver < Option < Address > > ,
46
+ allocations : & HashMap < Address , Allocation > ,
47
+ dispute_manager : & Address ,
82
48
) -> HashMap < thegraph_core:: Address , AttestationSigner > {
83
- let mut signers = attestation_signers_map. lock ( ) . await ;
84
- let allocations = allocations_rx. borrow ( ) . clone ( ) ;
85
- let Some ( dispute_manager) = * dispute_manager_rx. borrow ( ) else {
86
- return signers. clone ( ) ;
87
- } ;
49
+ let mut signers = attestation_signers_map. lock ( ) . unwrap ( ) ;
88
50
// Remove signers for allocations that are no longer active or recently closed
89
51
signers. retain ( |id, _| allocations. contains_key ( id) ) ;
90
52
91
53
// Create signers for new allocations
92
54
for ( id, allocation) in allocations. iter ( ) {
93
55
if !signers. contains_key ( id) {
94
56
let signer =
95
- AttestationSigner :: new ( & indexer_mnemonic, allocation, chain_id, dispute_manager) ;
57
+ AttestationSigner :: new ( indexer_mnemonic, allocation, chain_id, * dispute_manager) ;
96
58
match signer {
97
59
Ok ( signer) => {
98
60
signers. insert ( * id, signer) ;
@@ -113,24 +75,22 @@ async fn modify_sigers(
113
75
114
76
#[ cfg( test) ]
115
77
mod tests {
78
+ use tokio:: sync:: watch;
79
+
116
80
use crate :: test_vectors:: { DISPUTE_MANAGER_ADDRESS , INDEXER_ALLOCATIONS , INDEXER_MNEMONIC } ;
117
81
118
82
use super :: * ;
119
83
120
84
#[ tokio:: test]
121
85
async fn test_attestation_signers_update_with_allocations ( ) {
122
86
let ( allocations_tx, allocations_rx) = watch:: channel ( HashMap :: new ( ) ) ;
123
- let ( dispute_manager_tx, dispute_manager_rx) = watch:: channel ( None ) ;
124
- dispute_manager_tx
125
- . send ( Some ( * DISPUTE_MANAGER_ADDRESS ) )
126
- . unwrap ( ) ;
87
+ let ( _, dispute_manager_rx) = watch:: channel ( * DISPUTE_MANAGER_ADDRESS ) ;
127
88
let mut signers = attestation_signers (
128
89
allocations_rx,
129
90
INDEXER_MNEMONIC . clone ( ) ,
130
91
1 ,
131
92
dispute_manager_rx,
132
- )
133
- . await ;
93
+ ) ;
134
94
135
95
// Test that an empty set of allocations leads to an empty set of signers
136
96
allocations_tx. send ( HashMap :: new ( ) ) . unwrap ( ) ;
0 commit comments