@@ -10,6 +10,7 @@ import (
1010 "net/http"
1111 "net/url"
1212 "path"
13+ "slices"
1314 "strconv"
1415 "strings"
1516 "time"
@@ -111,14 +112,21 @@ func getAntiAbuseOracleAttestation(args GetAntiAbuseOracleAttestationParams) (*S
111112}
112113
113114// Selects three uniquely owned, healthy validators at random
114- // TODO: Remove hardcoded list, add health checks?
115- func getValidators (count int ) ([]string , error ) {
116- validators := []string {
117- "https://discoveryprovider.staging.audius.co" ,
118- "https://discoveryprovider2.staging.audius.co" ,
119- "https://discoveryprovider3.staging.audius.co" ,
120- }
121- return validators [:count ], nil
115+ // TODO: add health checks?
116+ func getValidators (validators []config.Node , count int , excludedOperators []string ) ([]string , error ) {
117+ shuffled := slices .Clone (validators )
118+ rand .Shuffle (min (len (validators ), count ), func (i , j int ) {
119+ shuffled [i ], shuffled [j ] = shuffled [j ], shuffled [i ]
120+ })
121+
122+ selected := make ([]string , 0 )
123+ for _ , node := range shuffled {
124+ if ! slices .Contains (excludedOperators , node .OperatorEthAddress ) {
125+ selected = append (selected , node .Endpoint )
126+ excludedOperators = append (excludedOperators , node .OperatorEthAddress )
127+ }
128+ }
129+ return selected , nil
122130}
123131
124132type GetValidatorAttestationParams struct {
@@ -407,7 +415,7 @@ func relayTransaction(relay string, transaction *solana.Transaction) (string, er
407415}
408416
409417// Claims an individual reward.
410- func claimReward (ctx context.Context , row dbv1.GetUndisbursedChallengesRow , antiAbuseOracleAddress string , antiAbuseOracleEndpoint string , rewardAttester * rewards.RewardAttester , solanaConfig config.SolanaConfig ) (string , error ) {
418+ func claimReward (ctx context.Context , row dbv1.GetUndisbursedChallengesRow , antiAbuseOracleAddress string , antiAbuseOracleEndpoint string , rewardAttester * rewards.RewardAttester , solanaConfig config.SolanaConfig , validators []config. Node ) (string , error ) {
411419 feePayer := solanaConfig .FeePayers [rand .IntN (len (solanaConfig .FeePayers ))]
412420
413421 rewardClaim := rewards.RewardClaim {
@@ -439,22 +447,44 @@ func claimReward(ctx context.Context, row dbv1.GetUndisbursedChallengesRow, anti
439447 }
440448 }
441449
450+ // Get current claim state
451+ disbursementId := rewardClaim .RewardID + ":" + rewardClaim .Specifier
452+ authority , _ , err := reward_manager .DeriveAuthorityAccount (reward_manager .ProgramID , solanaConfig .RewardManagerState )
453+ if err != nil {
454+ return "" , err
455+ }
456+ attestationsAccountAddress , _ , err := reward_manager .DeriveAttestationsAccount (reward_manager .ProgramID , authority , disbursementId )
457+ if err != nil {
458+ return "" , err
459+ }
460+ attestationsData := reward_manager.AttestationsAccountData {}
461+ err = client .GetAccountDataInto (ctx , attestationsAccountAddress , & attestationsData )
462+ if err != nil {
463+ return "" , err
464+ }
465+ existingOwners := make ([]string , 0 )
466+ for _ , attestation := range attestationsData .Messages {
467+ if attestation .Claim .AntiAbuseOracleEthAddress == "" {
468+ existingOwners = append (existingOwners , attestation .OperatorEthAddress )
469+ }
470+ }
471+
442472 // Attest from Bridge to get authority signature
443473 _ , signature , err := rewardAttester .Attest (rewardClaim )
444474 if err != nil {
445475 return "" , err
446476 }
447477
448478 // Fetch AAO and validator attestations
449- validators , err := getValidators (int (rewardManagerStateData .MinVotes ))
479+ selectedValidators , err := getValidators (validators , int (rewardManagerStateData .MinVotes ), existingOwners )
450480 if err != nil {
451481 return "" , err
452482 }
453483 aaoAttestation , validatorAttestations , err := fetchAttestations (
454484 ctx ,
455485 rewardClaim ,
456486 handle ,
457- validators ,
487+ selectedValidators ,
458488 antiAbuseOracleEndpoint ,
459489 antiAbuseOracleAddress ,
460490 signature ,
@@ -487,6 +517,7 @@ func claimReward(ctx context.Context, row dbv1.GetUndisbursedChallengesRow, anti
487517 }
488518
489519 return txSig , nil
520+ return "" , nil
490521}
491522
492523type HealthCheckResponse struct {
@@ -575,6 +606,7 @@ func (api *ApiServer) v1ClaimRewards(c *fiber.Ctx) error {
575606 antiAbuseOracleEndpoint ,
576607 & api .rewardAttester ,
577608 api .solanaConfig ,
609+ api .validators ,
578610 )
579611 signatures [i ] = sig
580612 return err
0 commit comments