@@ -15,6 +15,7 @@ import (
1515 "slices"
1616 "strconv"
1717 "strings"
18+ "sync"
1819 "time"
1920
2021 "bridgerton.audius.co/api/dbv1"
@@ -227,8 +228,7 @@ func getValidatorAttestation(args GetValidatorAttestationParams) (*SenderAttesta
227228// Gets reward claim attestations from AAO and Validators in parallel.
228229func fetchAttestations (
229230 ctx context.Context ,
230- rewardClaim rewards.RewardClaim ,
231- handle string ,
231+ rewardClaim RewardClaim ,
232232 validators []string ,
233233 antiAbuseOracle config.Node ,
234234 signature string ,
@@ -247,11 +247,11 @@ func fetchAttestations(
247247
248248 if ! hasAntiAbuseOracleAttestation {
249249 innerGroup .Go (func () error {
250- aaoClaim := rewardClaim
250+ aaoClaim := rewardClaim . RewardClaim
251251 aaoClaim .AntiAbuseOracleEthAddress = ""
252252 getAntiAbuseAttestationParams := GetAntiAbuseOracleAttestationParams {
253253 Claim : aaoClaim ,
254- Handle : handle ,
254+ Handle : rewardClaim . Handle ,
255255 AntiAbuseOracleEndpoint : antiAbuseOracle .Endpoint ,
256256 }
257257 aaoAttestation , err := getAntiAbuseOracleAttestation (getAntiAbuseAttestationParams )
@@ -267,7 +267,7 @@ func fetchAttestations(
267267 innerGroup .Go (func () error {
268268 getValidatorAttestationParams := GetValidatorAttestationParams {
269269 Validator : validator ,
270- Claim : rewardClaim ,
270+ Claim : rewardClaim . RewardClaim ,
271271 UserEthAddress : rewardClaim .RecipientEthAddress ,
272272 Signature : signature ,
273273 }
@@ -291,10 +291,9 @@ func fetchAttestations(
291291// Builds a Solana transaction to claim a reward from the attestations and sends it with retries.
292292func sendRewardClaimTransactions (
293293 ctx context.Context ,
294- userBank solana.PublicKey ,
295294 rewardManagerClient * reward_manager.RewardManagerClient ,
296295 transactionSender * spl.TransactionSender ,
297- rewardClaim rewards. RewardClaim ,
296+ rewardClaim RewardClaim ,
298297 attestations []SenderAttestation ,
299298) ([]solana.Signature , error ) {
300299 tx := solana .NewTransactionBuilder ()
@@ -379,7 +378,7 @@ func sendRewardClaimTransactions(
379378 common .HexToAddress (rewardClaim .AntiAbuseOracleEthAddress ),
380379 rewardManagerClient .GetProgramStateAccount (),
381380 state .TokenAccount ,
382- userBank ,
381+ rewardClaim . UserBank ,
383382 feePayer .PublicKey (),
384383 ).Build ()
385384 tx .AddInstruction (evaluateAttestationInstruction )
@@ -412,29 +411,20 @@ type RelayTransactionResponse struct {
412411// Claims an individual reward.
413412func claimReward (
414413 ctx context.Context ,
414+ rewardClaim RewardClaim ,
415415 rewardManagerClient * reward_manager.RewardManagerClient ,
416- row dbv1.GetUndisbursedChallengesRow ,
417- userBank solana.PublicKey ,
418- antiAbuseOracle config.Node ,
419416 rewardAttester * rewards.RewardAttester ,
420417 transactionSender * spl.TransactionSender ,
418+ antiAbuseOracle config.Node ,
421419 validators []config.Node ,
422420) ([]solana.Signature , error ) {
423- rewardClaim := rewards.RewardClaim {
424- RewardID : row .ChallengeID ,
425- Amount : uint64 (1000 ), // TODO: Change me!
426- Specifier : row .Specifier ,
427- RecipientEthAddress : row .Wallet .String ,
428- AntiAbuseOracleEthAddress : antiAbuseOracle .DelegateOwnerWallet ,
429- }
430- handle := row .Handle .String
431421
432422 rewardManagerStateData , err := rewardManagerClient .GetProgramState (ctx )
433423 if err != nil {
434424 return nil , err
435425 }
436426
437- attestationsData , err := rewardManagerClient .GetSubmittedAttestations (ctx , rewardClaim )
427+ attestationsData , err := rewardManagerClient .GetSubmittedAttestations (ctx , rewardClaim . RewardClaim )
438428 if err != nil {
439429 // If not found, then it's empty. Use default values for the purpose
440430 // of getting an empty list of messages
@@ -455,7 +445,7 @@ func claimReward(
455445 }
456446
457447 // Attest from Bridge to get authority signature
458- _ , signature , err := rewardAttester .Attest (rewardClaim )
448+ _ , signature , err := rewardAttester .Attest (rewardClaim . RewardClaim )
459449 if err != nil {
460450 return nil , err
461451 }
@@ -469,7 +459,6 @@ func claimReward(
469459 attestations , err := fetchAttestations (
470460 ctx ,
471461 rewardClaim ,
472- handle ,
473462 selectedValidators ,
474463 antiAbuseOracle ,
475464 signature ,
@@ -482,7 +471,6 @@ func claimReward(
482471 // Build and send solana transactions
483472 signatures , err := sendRewardClaimTransactions (
484473 ctx ,
485- userBank ,
486474 rewardManagerClient ,
487475 transactionSender ,
488476 rewardClaim ,
@@ -537,6 +525,29 @@ func getAntiAbuseOracle(antiAbuseOracleEndpoints []string) (node *config.Node, e
537525 }, nil
538526}
539527
528+ func getReward (rewardId string , rewardsList []rewards.Reward ) (rewards.Reward , error ) {
529+ for _ , r := range rewardsList {
530+ if r .RewardId == rewardId {
531+ return r , nil
532+ }
533+ }
534+ return rewards.Reward {}, fmt .Errorf ("challenge ID %s does not have a configured reward" , rewardId )
535+ }
536+
537+ type RewardClaim struct {
538+ rewards.RewardClaim
539+ Handle string
540+ UserBank solana.PublicKey
541+ }
542+
543+ type ClaimResult struct {
544+ ChallengeID string `json:"challengeId"`
545+ Specifier string `json:"specifier"`
546+ Amount uint64 `json:"amount"`
547+ Signatures []solana.Signature `json:"signatures"`
548+ Error string `json:"error,omitempty"`
549+ }
550+
540551// Claims all the filtered undisbursed rewards for a user.
541552func (api * ApiServer ) v1ClaimRewards (c * fiber.Ctx ) error {
542553 challengeId := c .Query ("challenge_id" )
@@ -573,26 +584,57 @@ func (api *ApiServer) v1ClaimRewards(c *fiber.Ctx) error {
573584 return err
574585 }
575586
576- signatures := make (map [string ]map [string ][]solana.Signature )
587+ bankAccount , err := claimable_tokens .DeriveUserBankAccount (
588+ api .solanaConfig .MintAudio ,
589+ undisbursedRows [0 ].Wallet .String ,
590+ )
591+ if err != nil {
592+ return err
593+ }
594+
595+ results := make ([]ClaimResult , len (undisbursedRows ))
577596 ctx , cancel := context .WithTimeout (context .Background (), 120 * time .Second )
578597 defer cancel ()
579- g , ctx := errgroup .WithContext (ctx )
580- for _ , row := range undisbursedRows {
581- bankAccount , err := claimable_tokens .DeriveUserBankAccount (api .solanaConfig .MintAudio , row .Wallet .String )
582- if err != nil {
583- return err
584- }
585- g .Go (func () error {
586- sig , err := claimReward (
598+ g := & sync.WaitGroup {}
599+ g .Add (len (undisbursedRows ))
600+ for i , row := range undisbursedRows {
601+ go func () {
602+ results [i ] = ClaimResult {
603+ ChallengeID : row .ChallengeID ,
604+ Specifier : row .Specifier ,
605+ }
606+
607+ reward , err := getReward (row .ChallengeID , api .rewardAttester .Rewards )
608+ if err != nil {
609+ results [i ].Error = err .Error ()
610+ g .Done ()
611+ return
612+ }
613+
614+ results [i ].Amount = reward .Amount
615+
616+ rewardClaim := RewardClaim {
617+ RewardClaim : rewards.RewardClaim {
618+ RewardID : row .ChallengeID ,
619+ Amount : reward .Amount ,
620+ Specifier : row .Specifier ,
621+ RecipientEthAddress : row .Wallet .String ,
622+ AntiAbuseOracleEthAddress : antiAbuseOracle .DelegateOwnerWallet ,
623+ },
624+ Handle : row .Handle .String ,
625+ UserBank : bankAccount ,
626+ }
627+
628+ sigs , err := claimReward (
587629 ctx ,
630+ rewardClaim ,
588631 & api .rewardManagerClient ,
589- row ,
590- bankAccount ,
591- * antiAbuseOracle ,
592632 & api .rewardAttester ,
593633 & api .transactionSender ,
634+ * antiAbuseOracle ,
594635 api .validators ,
595636 )
637+
596638 if err != nil {
597639 var instrErr * spl.InstructionError
598640 if errors .As (err , & instrErr ) {
@@ -612,21 +654,16 @@ func (api *ApiServer) v1ClaimRewards(c *fiber.Ctx) error {
612654 zap .Error (err ),
613655 )
614656 }
615- return err
616- }
617- if signatures [row .ChallengeID ] == nil {
618- signatures [row .ChallengeID ] = make (map [string ][]solana.Signature )
657+ results [i ].Error = err .Error ()
619658 }
620- signatures [row.ChallengeID ][row.Specifier ] = sig
621- return nil
622- })
623- }
624- err = g .Wait ()
625- if err != nil {
626- return err
659+
660+ results [i ].Signatures = sigs
661+ g .Done ()
662+ }()
627663 }
664+ g .Wait ()
628665
629666 return c .Status (http .StatusOK ).JSON (fiber.Map {
630- "data" : signatures ,
667+ "data" : results ,
631668 })
632669}
0 commit comments