22// SPDX-License-Identifier: Apache-2.0
33
44use bip39:: Mnemonic ;
5- use std:: collections:: HashMap ;
65use std:: sync:: Arc ;
6+ use std:: { collections:: HashMap , sync:: Mutex } ;
77use 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 ;
159use tracing:: warn;
1610
17- use crate :: prelude:: { Allocation , AttestationSigner } ;
11+ use crate :: {
12+ prelude:: { Allocation , AttestationSigner } ,
13+ watcher:: join_and_map_watcher,
14+ } ;
1815
1916/// 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 > > ,
2219 indexer_mnemonic : Mnemonic ,
2320 chain_id : ChainId ,
24- mut dispute_manager_rx : Receiver < Option < Address > > ,
21+ dispute_manager_rx : Receiver < Address > ,
2522) -> Receiver < HashMap < Address , AttestationSigner > > {
2623 let attestation_signers_map: & ' static Mutex < HashMap < Address , AttestationSigner > > =
2724 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 ( ) ) ;
2926
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+ } ,
3640 )
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
7541}
76- async fn modify_sigers (
77- indexer_mnemonic : Arc < String > ,
42+ fn modify_sigers (
43+ indexer_mnemonic : & str ,
7844 chain_id : ChainId ,
7945 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 ,
8248) -> 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 ( ) ;
8850 // Remove signers for allocations that are no longer active or recently closed
8951 signers. retain ( |id, _| allocations. contains_key ( id) ) ;
9052
9153 // Create signers for new allocations
9254 for ( id, allocation) in allocations. iter ( ) {
9355 if !signers. contains_key ( id) {
9456 let signer =
95- AttestationSigner :: new ( & indexer_mnemonic, allocation, chain_id, dispute_manager) ;
57+ AttestationSigner :: new ( indexer_mnemonic, allocation, chain_id, * dispute_manager) ;
9658 match signer {
9759 Ok ( signer) => {
9860 signers. insert ( * id, signer) ;
@@ -113,24 +75,22 @@ async fn modify_sigers(
11375
11476#[ cfg( test) ]
11577mod tests {
78+ use tokio:: sync:: watch;
79+
11680 use crate :: test_vectors:: { DISPUTE_MANAGER_ADDRESS , INDEXER_ALLOCATIONS , INDEXER_MNEMONIC } ;
11781
11882 use super :: * ;
11983
12084 #[ tokio:: test]
12185 async fn test_attestation_signers_update_with_allocations ( ) {
12286 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 ) ;
12788 let mut signers = attestation_signers (
12889 allocations_rx,
12990 INDEXER_MNEMONIC . clone ( ) ,
13091 1 ,
13192 dispute_manager_rx,
132- )
133- . await ;
93+ ) ;
13494
13595 // Test that an empty set of allocations leads to an empty set of signers
13696 allocations_tx. send ( HashMap :: new ( ) ) . unwrap ( ) ;
0 commit comments