99
1010 "api.audius.co/database"
1111 "api.audius.co/solana/indexer/common"
12- "api.audius.co/solana/spl/programs/meteora_dbc"
1312 "api.audius.co/solana/spl/programs/meteora_locker"
1413 bin "github.com/gagliardetto/binary"
1514 "github.com/gagliardetto/solana-go"
@@ -22,8 +21,8 @@ import (
2221
2322const (
2423 NAME = "LockerIndexer"
25- MAX_POOLS_PER_SUBSCRIPTION = 10000 // Arbitrary
26- NOTIFICATION_NAME = "dbc_pools_changed "
24+ MAX_MINTS_PER_SUBSCRIPTION = 10000 // Arbitrary
25+ NOTIFICATION_NAME = "artist_coins_changed "
2726)
2827
2928type Indexer struct {
@@ -145,32 +144,27 @@ func (d *Indexer) Start(ctx context.Context) {
145144}
146145
147146func (d * Indexer ) subscribe (ctx context.Context ) ([]common.GrpcClient , error ) {
148- // Fetch all DBC pools
149- pools , err := getAllDbcPools (ctx , d .pool )
150- if err != nil {
151- return nil , fmt .Errorf ("failed to fetch DBC pools: %w" , err )
152- }
153-
154- d .logger .Info ("subscribing to dbc pools" , zap .Int ("numPools" , len (pools )))
155-
156- // Create gRPC clients for each subscription batch
157- var grpcClients []common.GrpcClient
158-
159- // Subscribe in batches to avoid exceeding limits
160- for i := 0 ; i < len (pools ); i += MAX_POOLS_PER_SUBSCRIPTION {
161- end := i + MAX_POOLS_PER_SUBSCRIPTION
162- if end > len (pools ) {
163- end = len (pools )
147+ done := false
148+ page := 0
149+ pageSize := MAX_MINTS_PER_SUBSCRIPTION
150+ grpcClients := make ([]common.GrpcClient , 0 )
151+ total := 0
152+ for ! done {
153+ mints , err := common .GetArtistCoinMints (ctx , d .pool , pageSize , page * pageSize )
154+ if err != nil {
155+ return nil , fmt .Errorf ("failed to get artist coins: %w" , err )
156+ }
157+ if len (mints ) == 0 {
158+ d .logger .Info ("no more artist coins to subscribe to, exiting" )
159+ return grpcClients , nil
160+ }
161+ total += len (mints )
162+ d .logger .Debug ("subscribing to artist coins..." , zap .Int ("count" , len (mints )))
163+ subscription , err := d .makeSubscriptionRequest (ctx , mints )
164+ if err != nil {
165+ return nil , fmt .Errorf ("failed to make mint subscription request: %w" , err )
164166 }
165- batch := pools [i :end ]
166-
167- d .logger .Info ("creating locker subscription batch" ,
168- zap .Int ("startIndex" , i ),
169- zap .Int ("endIndex" , end ),
170- zap .Int ("batchSize" , len (batch )),
171- )
172167
173- subscription := d .makeSubscriptionRequest (ctx , batch )
174168 handleMessage := func (ctx context.Context , update * pb.SubscribeUpdate ) {
175169 err := d .HandleUpdate (ctx , update )
176170 if err != nil {
@@ -182,47 +176,56 @@ func (d *Indexer) subscribe(ctx context.Context) ([]common.GrpcClient, error) {
182176 }
183177 }
184178
185- client := common .NewGrpcClient (d .grpcConfig )
186- err := client .Subscribe (ctx , subscription , handleMessage , func (err error ) {
187- d .logger .Error ("subscription error" , zap .Error (err ))
179+ grpcClient := common .NewGrpcClient (d .grpcConfig )
180+ err = grpcClient .Subscribe (ctx , subscription , handleMessage , func (err error ) {
181+ d .logger .Error ("error in token subscription " , zap .Error (err ))
188182 })
189183 if err != nil {
190- return nil , fmt .Errorf ("failed to start subscription : %w" , err )
184+ return nil , fmt .Errorf ("failed to subscribe to artist coins : %w" , err )
191185 }
186+ grpcClients = append (grpcClients , grpcClient )
192187
193- d .logger .Info ("subscribed to locker programs" ,
194- zap .Int ("numPools" , len (batch )),
195- )
196-
197- grpcClients = append (grpcClients , client )
188+ if len (mints ) < pageSize {
189+ done = true
190+ }
191+ page ++
198192 }
199-
193+ d . logger . Info ( "subscribed to artist coins" , zap . Int ( "count" , total ))
200194 return grpcClients , nil
201195}
202196
203197// Makes a subscription to the relevant locker accounts and adds slot checkpointing
204- func (d * Indexer ) makeSubscriptionRequest (ctx context.Context , pools []string ) * pb.SubscribeRequest {
198+ func (d * Indexer ) makeSubscriptionRequest (ctx context.Context , mints []string ) ( * pb.SubscribeRequest , error ) {
205199 commitment := pb .CommitmentLevel_CONFIRMED
206200 subscription := & pb.SubscribeRequest {
207201 Commitment : & commitment ,
208202 }
209203
210204 // Listen to all lockers
211205 subscription .Accounts = make (map [string ]* pb.SubscribeRequestFilterAccounts )
212- subscription .Accounts ["lockers" ] = & pb.SubscribeRequestFilterAccounts {
213- Owner : []string {meteora_locker .ProgramID .String ()},
214- Account : make ([]string , len (pools )),
215- }
216- for i , pool := range pools {
217- baseKey := meteora_dbc .DeriveBaseKeyForEscrow (solana .MustPublicKeyFromBase58 (pool ))
218- escrowKey := meteora_dbc .DeriveEscrow (baseKey )
219- subscription .Accounts ["lockers" ].Account [i ] = escrowKey .String ()
206+ for _ , mint := range mints {
207+ accountFilter := pb.SubscribeRequestFilterAccounts {
208+ Owner : []string {meteora_locker .ProgramID .String ()},
209+ Filters : []* pb.SubscribeRequestFilterAccountsFilter {
210+ {
211+ Filter : & pb.SubscribeRequestFilterAccountsFilter_Memcmp {
212+ Memcmp : & pb.SubscribeRequestFilterAccountsFilterMemcmp {
213+ Offset : 8 + 32 , // Discriminator + recipient pubkey
214+ Data : & pb.SubscribeRequestFilterAccountsFilterMemcmp_Base58 {
215+ Base58 : mint ,
216+ },
217+ },
218+ },
219+ },
220+ },
221+ }
222+ subscription .Accounts [mint ] = & accountFilter
220223 }
221224
222225 // Ensure this subscription has a checkpoint
223226 checkpointId , fromSlot , err := common .EnsureCheckpoint (ctx , NAME , d .pool , d .rpcClient , subscription , d .logger )
224227 if err != nil {
225- d . logger . Error ("failed to ensure checkpoint " , zap . Error ( err ) )
228+ return nil , fmt . Errorf ("failed to set from slot: %w " , err )
226229 }
227230
228231 // Set the from slot for the subscription
@@ -232,7 +235,7 @@ func (d *Indexer) makeSubscriptionRequest(ctx context.Context, pools []string) *
232235 subscription .Slots = make (map [string ]* pb.SubscribeRequestFilterSlots )
233236 subscription .Slots [checkpointId ] = & pb.SubscribeRequestFilterSlots {}
234237
235- return subscription
238+ return subscription , nil
236239}
237240
238241func (d * Indexer ) HandleUpdate (ctx context.Context , update * pb.SubscribeUpdate ) error {
@@ -287,19 +290,3 @@ func processLockerAccountUpdate(
287290
288291 return nil
289292}
290-
291- func getAllDbcPools (ctx context.Context , db database.DBTX ) ([]string , error ) {
292- sql := `
293- SELECT account
294- FROM sol_meteora_dbc_pools
295- `
296- rows , err := db .Query (ctx , sql )
297- if err != nil {
298- return nil , fmt .Errorf ("failed to query dbc pools: %w" , err )
299- }
300- pools , err := pgx .CollectRows (rows , pgx .RowTo [string ])
301- if err != nil {
302- return nil , fmt .Errorf ("failed to collect dbc pools: %w" , err )
303- }
304- return pools , nil
305- }
0 commit comments