66 "encoding/hex"
77 "encoding/json"
88 "fmt"
9+ "github.com/deso-protocol/core/collections"
910 "github.com/deso-protocol/uint256"
1011 "io"
1112 "math"
@@ -2331,56 +2332,7 @@ func (fes *APIServer) GetNotifications(ww http.ResponseWriter, req *http.Request
23312332 }
23322333
23332334 for _ , txnMeta := range finalTxnMetadataList {
2334- postMetadata := txnMeta .Metadata .SubmitPostTxindexMetadata
2335- likeMetadata := txnMeta .Metadata .LikeTxindexMetadata
2336- transferCreatorCoinMetadata := txnMeta .Metadata .CreatorCoinTransferTxindexMetadata
2337- nftBidMetadata := txnMeta .Metadata .NFTBidTxindexMetadata
2338- acceptNFTBidMetadata := txnMeta .Metadata .AcceptNFTBidTxindexMetadata
2339- nftTransferMetadata := txnMeta .Metadata .NFTTransferTxindexMetadata
2340- basicTransferMetadata := txnMeta .Metadata .BasicTransferTxindexMetadata
2341- createNFTMetadata := txnMeta .Metadata .CreateNFTTxindexMetadata
2342- updateNFTMetadata := txnMeta .Metadata .UpdateNFTTxindexMetadata
2343- postAssociationMetadata := txnMeta .Metadata .CreatePostAssociationTxindexMetadata
2344-
2345- if postMetadata != nil {
2346- addPostForHash (postMetadata .PostHashBeingModifiedHex , userPublicKeyBytes )
2347- addPostForHash (postMetadata .ParentPostHashHex , userPublicKeyBytes )
2348- } else if likeMetadata != nil {
2349- addPostForHash (likeMetadata .PostHashHex , userPublicKeyBytes )
2350- } else if transferCreatorCoinMetadata != nil {
2351- if transferCreatorCoinMetadata .PostHashHex != "" {
2352- addPostForHash (transferCreatorCoinMetadata .PostHashHex , userPublicKeyBytes )
2353- }
2354- } else if nftBidMetadata != nil {
2355- addPostForHash (nftBidMetadata .NFTPostHashHex , userPublicKeyBytes )
2356- } else if acceptNFTBidMetadata != nil {
2357- addPostForHash (acceptNFTBidMetadata .NFTPostHashHex , userPublicKeyBytes )
2358- } else if nftTransferMetadata != nil {
2359- addPostForHash (nftTransferMetadata .NFTPostHashHex , userPublicKeyBytes )
2360- } else if createNFTMetadata != nil {
2361- addPostForHash (createNFTMetadata .NFTPostHashHex , userPublicKeyBytes )
2362- } else if updateNFTMetadata != nil {
2363- addPostForHash (updateNFTMetadata .NFTPostHashHex , userPublicKeyBytes )
2364- } else if postAssociationMetadata != nil {
2365- addPostForHash (postAssociationMetadata .PostHashHex , userPublicKeyBytes )
2366- } else if basicTransferMetadata != nil {
2367- txnOutputs := txnMeta .Metadata .TxnOutputs
2368- for _ , output := range txnOutputs {
2369- txnMeta .TxnOutputResponses = append (
2370- txnMeta .TxnOutputResponses ,
2371- & OutputResponse {
2372- PublicKeyBase58Check : lib .PkToString (output .PublicKey , fes .Params ),
2373- AmountNanos : output .AmountNanos ,
2374- })
2375- }
2376- if basicTransferMetadata .PostHashHex != "" {
2377- addPostForHash (basicTransferMetadata .PostHashHex , userPublicKeyBytes )
2378- }
2379- }
2380-
2381- // Delete the UTXO ops because they aren't needed for the frontend
2382- basicTransferMetadata .UtxoOps = nil
2383- basicTransferMetadata .UtxoOpsDump = ""
2335+ fes .addPostForHashForNotification (txnMeta , txnMeta .Metadata , userPublicKeyBytes , addPostForHash , nil )
23842336 }
23852337
23862338 var lastSeenIndex int64
@@ -2399,12 +2351,100 @@ func (fes *APIServer) GetNotifications(ww http.ResponseWriter, req *http.Request
23992351 LastSeenIndex : lastSeenIndex ,
24002352 }
24012353 if err = json .NewEncoder (ww ).Encode (res ); err != nil {
2354+ fmt .Printf ("%#v\n " , res )
24022355 _AddBadRequestError (ww , fmt .Sprintf (
24032356 "GetNotifications: Problem encoding response as JSON: %v" , err ))
24042357 return
24052358 }
24062359}
24072360
2361+ func (fes * APIServer ) addPostForHashForNotification (
2362+ txnMetaRes * TransactionMetadataResponse ,
2363+ txnMeta * lib.TransactionMetadata ,
2364+ userPublicKeyBytes []byte ,
2365+ addPostForHash func (postHashHex string , readerPK []byte ),
2366+ indexInAtomic * int ,
2367+ ) {
2368+ postMetadata := txnMeta .SubmitPostTxindexMetadata
2369+ likeMetadata := txnMeta .LikeTxindexMetadata
2370+ transferCreatorCoinMetadata := txnMeta .CreatorCoinTransferTxindexMetadata
2371+ nftBidMetadata := txnMeta .NFTBidTxindexMetadata
2372+ acceptNFTBidMetadata := txnMeta .AcceptNFTBidTxindexMetadata
2373+ nftTransferMetadata := txnMeta .NFTTransferTxindexMetadata
2374+ basicTransferMetadata := txnMeta .BasicTransferTxindexMetadata
2375+ createNFTMetadata := txnMeta .CreateNFTTxindexMetadata
2376+ updateNFTMetadata := txnMeta .UpdateNFTTxindexMetadata
2377+ postAssociationMetadata := txnMeta .CreatePostAssociationTxindexMetadata
2378+ atomicTxnMetadata := txnMeta .AtomicTxnsWrapperTxindexMetadata
2379+ if atomicTxnMetadata != nil {
2380+ for ii , innerTxn := range atomicTxnMetadata .InnerTxnsTransactionMetadata {
2381+ fes .addPostForHashForNotification (txnMetaRes , innerTxn , userPublicKeyBytes , addPostForHash , & ii )
2382+ innerTxn .BasicTransferTxindexMetadata .UtxoOps = nil
2383+ innerTxn .BasicTransferTxindexMetadata .UtxoOpsDump = ""
2384+ }
2385+ }
2386+ if atomicTxnMetadata != nil {
2387+ for ii , innerTxn := range atomicTxnMetadata .InnerTxnsTransactionMetadata {
2388+ fes .addPostForHashForNotification (txnMetaRes , innerTxn , userPublicKeyBytes , addPostForHash , & ii )
2389+ innerTxn .BasicTransferTxindexMetadata .UtxoOps = nil
2390+ innerTxn .BasicTransferTxindexMetadata .UtxoOpsDump = ""
2391+ }
2392+ }
2393+
2394+ if postMetadata != nil {
2395+ addPostForHash (postMetadata .PostHashBeingModifiedHex , userPublicKeyBytes )
2396+ addPostForHash (postMetadata .ParentPostHashHex , userPublicKeyBytes )
2397+ } else if likeMetadata != nil {
2398+ addPostForHash (likeMetadata .PostHashHex , userPublicKeyBytes )
2399+ } else if transferCreatorCoinMetadata != nil {
2400+ if transferCreatorCoinMetadata .PostHashHex != "" {
2401+ addPostForHash (transferCreatorCoinMetadata .PostHashHex , userPublicKeyBytes )
2402+ }
2403+ } else if nftBidMetadata != nil {
2404+ addPostForHash (nftBidMetadata .NFTPostHashHex , userPublicKeyBytes )
2405+ } else if acceptNFTBidMetadata != nil {
2406+ addPostForHash (acceptNFTBidMetadata .NFTPostHashHex , userPublicKeyBytes )
2407+ } else if nftTransferMetadata != nil {
2408+ addPostForHash (nftTransferMetadata .NFTPostHashHex , userPublicKeyBytes )
2409+ } else if createNFTMetadata != nil {
2410+ addPostForHash (createNFTMetadata .NFTPostHashHex , userPublicKeyBytes )
2411+ } else if updateNFTMetadata != nil {
2412+ addPostForHash (updateNFTMetadata .NFTPostHashHex , userPublicKeyBytes )
2413+ } else if postAssociationMetadata != nil {
2414+ addPostForHash (postAssociationMetadata .PostHashHex , userPublicKeyBytes )
2415+ } else if basicTransferMetadata != nil {
2416+ txnOutputs := txnMeta .TxnOutputs
2417+ for _ , output := range txnOutputs {
2418+ txnMetaRes .TxnOutputResponses = append (
2419+ txnMetaRes .TxnOutputResponses ,
2420+ & OutputResponse {
2421+ PublicKeyBase58Check : lib .PkToString (output .PublicKey , fes .Params ),
2422+ AmountNanos : output .AmountNanos ,
2423+ })
2424+ if indexInAtomic != nil {
2425+ if txnMetaRes .InnerTxnOutputResponses == nil {
2426+ txnMetaRes .InnerTxnOutputResponses = make (map [int ][]* OutputResponse )
2427+ }
2428+ txnMetaRes .InnerTxnOutputResponses [* indexInAtomic ] = append (
2429+ txnMetaRes .InnerTxnOutputResponses [* indexInAtomic ],
2430+ & OutputResponse {
2431+ PublicKeyBase58Check : lib .PkToString (output .PublicKey , fes .Params ),
2432+ AmountNanos : output .AmountNanos ,
2433+ })
2434+ }
2435+ }
2436+ if basicTransferMetadata .PostHashHex != "" {
2437+ addPostForHash (basicTransferMetadata .PostHashHex , userPublicKeyBytes )
2438+ }
2439+ }
2440+
2441+ // Delete the UTXO ops because they aren't needed for the frontend
2442+ txnMeta .BasicTransferTxindexMetadata .UtxoOps = nil
2443+ txnMeta .BasicTransferTxindexMetadata .UtxoOpsDump = ""
2444+ basicTransferMetadata .UtxoOps = nil
2445+ basicTransferMetadata .UtxoOpsDump = ""
2446+ }
2447+
24082448type SetNotificationMetadataRequest struct {
24092449 PublicKeyBase58Check string
24102450 // The last notification index the user has seen
@@ -2520,46 +2560,38 @@ func (fes *APIServer) _getDBNotifications(request *GetNotificationsRequest, bloc
25202560
25212561 // In this case we need to look up the full transaction and convert
25222562 // it into a proper transaction response.
2523- dbTxnMeta := lib .DbGetTxindexTransactionRefByTxID (fes .TXIndex .TXIndexChain .DB (), nil , txID )
2524- if dbTxnMeta == nil {
2563+ txnMeta := lib .DbGetTxindexTransactionRefByTxID (fes .TXIndex .TXIndexChain .DB (), nil , txID )
2564+ if txnMeta == nil {
25252565 // We should never be missing a transaction for a given txid, but
25262566 // just continue in this case.
25272567 glog .Errorf ("GetNotifications: Missing TransactionMetadata for txid %v" , txID )
25282568 continue
25292569 }
2530- txnMetas := []* lib.TransactionMetadata {dbTxnMeta }
2531- if dbTxnMeta .AtomicTxnsWrapperTxindexMetadata != nil {
2532- // If this is an atomic transaction, we need to iterate over the inner transactions
2533- // and convert them into TransactionMetadata objects.
2534- txnMetas = dbTxnMeta .AtomicTxnsWrapperTxindexMetadata .InnerTxnsTransactionMetadata
2570+ // Skip transactions that aren't notifications
2571+ if ! TxnMetaIsNotification (txnMeta , request .PublicKeyBase58Check , utxoView ) {
2572+ continue
25352573 }
2536- for _ , txnMeta := range txnMetas {
2537- // Skip transactions that aren't notifications
2538- if ! TxnMetaIsNotification (txnMeta , request .PublicKeyBase58Check , utxoView ) {
2539- continue
2540- }
2541- transactorPkBytes , _ , err := lib .Base58CheckDecode (txnMeta .TransactorPublicKeyBase58Check )
2542- if err != nil {
2543- glog .Errorf ("GetNotifications: unable to decode public key %v" , txnMeta .TransactorPublicKeyBase58Check )
2544- continue
2545- }
2546- // Skip transactions from blocked users.
2547- if _ , ok := blockedPubKeys [lib .PkToString (transactorPkBytes , fes .Params )]; ok {
2548- continue
2549- }
2550- // Skip transactions from blacklisted public keys
2551- transactorPKID := utxoView .GetPKIDForPublicKey (transactorPkBytes )
2552- if transactorPKID == nil || fes .IsUserBlacklisted (transactorPKID .PKID , utxoView ) {
2553- continue
2554- }
2555- currentIndexBytes := keysFound [ii ][len (lib .DbTxindexPublicKeyPrefix (pkBytes )):]
2556- res := & TransactionMetadataResponse {
2557- Metadata : txnMeta ,
2558- Index : int64 (lib .DecodeUint32 (currentIndexBytes )),
2559- }
2560- if NotificationTxnShouldBeIncluded (res .Metadata , & filteredOutCategories ) {
2561- dbTxnMetadataFound = append (dbTxnMetadataFound , res )
2562- }
2574+ transactorPkBytes , _ , err := lib .Base58CheckDecode (txnMeta .TransactorPublicKeyBase58Check )
2575+ if err != nil {
2576+ glog .Errorf ("GetNotifications: unable to decode public key %v" , txnMeta .TransactorPublicKeyBase58Check )
2577+ continue
2578+ }
2579+ // Skip transactions from blocked users.
2580+ if _ , ok := blockedPubKeys [lib .PkToString (transactorPkBytes , fes .Params )]; ok {
2581+ continue
2582+ }
2583+ // Skip transactions from blacklisted public keys
2584+ transactorPKID := utxoView .GetPKIDForPublicKey (transactorPkBytes )
2585+ if transactorPKID == nil || fes .IsUserBlacklisted (transactorPKID .PKID , utxoView ) {
2586+ continue
2587+ }
2588+ currentIndexBytes := keysFound [ii ][len (lib .DbTxindexPublicKeyPrefix (pkBytes )):]
2589+ res := & TransactionMetadataResponse {
2590+ Metadata : txnMeta ,
2591+ Index : int64 (lib .DecodeUint32 (currentIndexBytes )),
2592+ }
2593+ if NotificationTxnShouldBeIncluded (res .Metadata , & filteredOutCategories ) {
2594+ dbTxnMetadataFound = append (dbTxnMetadataFound , res )
25632595 }
25642596 }
25652597
@@ -2633,60 +2665,51 @@ func (fes *APIServer) _getMempoolNotifications(request *GetNotificationsRequest,
26332665
26342666 mempoolTxnMetadata := []* TransactionMetadataResponse {}
26352667 for _ , poolTx := range poolTxns {
2636- poolTxnMeta := poolTx .TxMeta
2637- if poolTxnMeta == nil {
2668+ txnMeta := poolTx .TxMeta
2669+ if txnMeta == nil {
26382670 continue
26392671 }
26402672
26412673 // Set the current index we will use to identify this transaction.
26422674 currentIndex := NextIndex
26432675
2644- txnMetas := [] * lib. TransactionMetadata { poolTxnMeta }
2645- if poolTxnMeta . AtomicTxnsWrapperTxindexMetadata != nil {
2646- // If this is an atomic transaction, we need to iterate over the inner transactions
2647- // and convert them into TransactionMetadata objects.
2648- txnMetas = poolTxnMeta . AtomicTxnsWrapperTxindexMetadata . InnerTxnsTransactionMetadata
2676+ // Increment the NextIndex if this transaction is associated with the user's
2677+ // public key in any way. This is what the db would do when storing it, and so
2678+ // this treatment should be consistent.
2679+ if TxnIsAssociatedWithPublicKey ( txnMeta , request . PublicKeyBase58Check ) {
2680+ NextIndex ++
26492681 }
2650- for _ , txnMeta := range txnMetas {
26512682
2652- // Increment the NextIndex if this transaction is associated with the user's
2653- // public key in any way. This is what the db would do when storing it, and so
2654- // this treatment should be consistent.
2655- if TxnIsAssociatedWithPublicKey (txnMeta , request .PublicKeyBase58Check ) {
2656- NextIndex ++
2683+ // If the transaction is a notification then add it to our list with the proper
2684+ // index value if the transactor is not a blocked public key
2685+ if TxnMetaIsNotification (txnMeta , request .PublicKeyBase58Check , utxoView ) {
2686+ transactorPkBytes , _ , err := lib .Base58CheckDecode (txnMeta .TransactorPublicKeyBase58Check )
2687+ if err != nil {
2688+ glog .Errorf ("GetNotifications: unable to decode public key %v" , txnMeta .TransactorPublicKeyBase58Check )
2689+ continue
26572690 }
26582691
2659- // If the transaction is a notification then add it to our list with the proper
2660- // index value if the transactor is not a blocked public key
2661- if TxnMetaIsNotification (txnMeta , request .PublicKeyBase58Check , utxoView ) {
2662- transactorPkBytes , _ , err := lib .Base58CheckDecode (txnMeta .TransactorPublicKeyBase58Check )
2663- if err != nil {
2664- glog .Errorf ("GetNotifications: unable to decode public key %v" , txnMeta .TransactorPublicKeyBase58Check )
2665- continue
2666- }
2667-
2668- // Skip transactions from blocked users.
2669- if _ , ok := blockedPubKeys [lib .PkToString (transactorPkBytes , fes .Params )]; ok {
2670- continue
2671- }
2672- // Skip blacklisted public keys
2673- transactorPKID := utxoView .GetPKIDForPublicKey (transactorPkBytes )
2674- if transactorPKID == nil || fes .IsUserBlacklisted (transactorPKID .PKID , utxoView ) {
2675- continue
2676- }
2692+ // Skip transactions from blocked users.
2693+ if _ , ok := blockedPubKeys [lib .PkToString (transactorPkBytes , fes .Params )]; ok {
2694+ continue
2695+ }
2696+ // Skip blacklisted public keys
2697+ transactorPKID := utxoView .GetPKIDForPublicKey (transactorPkBytes )
2698+ if transactorPKID == nil || fes .IsUserBlacklisted (transactorPKID .PKID , utxoView ) {
2699+ continue
2700+ }
26772701
2678- // Skip transactions when notification should not be included based on filter
2679- if ! NotificationTxnShouldBeIncluded (txnMeta , & filteredOutCategories ) {
2680- continue
2681- }
2702+ // Skip transactions when notification should not be included based on filter
2703+ if ! NotificationTxnShouldBeIncluded (txnMeta , & filteredOutCategories ) {
2704+ continue
2705+ }
26822706
2683- // Only include transactions that occur on or after the start index, if defined
2684- if request .FetchStartIndex < 0 || (request .FetchStartIndex >= currentIndex && iterateReverse ) || (request .FetchStartIndex <= currentIndex && ! iterateReverse ) {
2685- mempoolTxnMetadata = append (mempoolTxnMetadata , & TransactionMetadataResponse {
2686- Metadata : txnMeta ,
2687- Index : currentIndex ,
2688- })
2689- }
2707+ // Only include transactions that occur on or after the start index, if defined
2708+ if request .FetchStartIndex < 0 || (request .FetchStartIndex >= currentIndex && iterateReverse ) || (request .FetchStartIndex <= currentIndex && ! iterateReverse ) {
2709+ mempoolTxnMetadata = append (mempoolTxnMetadata , & TransactionMetadataResponse {
2710+ Metadata : txnMeta ,
2711+ Index : currentIndex ,
2712+ })
26902713 }
26912714 }
26922715
@@ -2876,6 +2899,12 @@ func NotificationTxnShouldBeIncluded(txnMeta *lib.TransactionMetadata, filteredO
28762899 } else if txnMeta .TxnType == lib .TxnTypeCreateUserAssociation .String () ||
28772900 txnMeta .TxnType == lib .TxnTypeDeleteUserAssociation .String () {
28782901 return ! filteredOutCategories ["user association" ]
2902+ } else if txnMeta .TxnType == lib .TxnTypeAtomicTxnsWrapper .String () {
2903+ // If any of the component transactions would be included, then this atomic txn should be included.
2904+ return collections .Any (txnMeta .AtomicTxnsWrapperTxindexMetadata .InnerTxnsTransactionMetadata ,
2905+ func (innerTxnMeta * lib.TransactionMetadata ) bool {
2906+ return NotificationTxnShouldBeIncluded (innerTxnMeta , filteredOutCategoriesPointer )
2907+ })
28792908 }
28802909 // If the transaction type doesn't fall into any of the previous steps, we don't want it
28812910 return false
@@ -2972,6 +3001,12 @@ func TxnMetaIsNotification(txnMeta *lib.TransactionMetadata, publicKeyBase58Chec
29723001 } else if txnMeta .CreatePostAssociationTxindexMetadata != nil {
29733002 // Some created an association referring to one of your posts
29743003 return true
3004+ } else if txnMeta .AtomicTxnsWrapperTxindexMetadata != nil {
3005+ // If any of the component transactions would trigger a notification, then this atomic txn should trigger a notification.
3006+ return collections .Any (txnMeta .AtomicTxnsWrapperTxindexMetadata .InnerTxnsTransactionMetadata ,
3007+ func (innerTxnMeta * lib.TransactionMetadata ) bool {
3008+ return TxnMetaIsNotification (innerTxnMeta , publicKeyBase58Check , utxoView )
3009+ })
29753010 }
29763011 return false
29773012}
@@ -2989,10 +3024,11 @@ func TxnIsAssociatedWithPublicKey(txnMeta *lib.TransactionMetadata, publicKeyBas
29893024}
29903025
29913026type TransactionMetadataResponse struct {
2992- Metadata * lib.TransactionMetadata
2993- TxnOutputResponses []* OutputResponse
2994- Txn * TransactionResponse
2995- Index int64
3027+ Metadata * lib.TransactionMetadata
3028+ TxnOutputResponses []* OutputResponse
3029+ InnerTxnOutputResponses map [int ][]* OutputResponse
3030+ Txn * TransactionResponse
3031+ Index int64
29963032}
29973033
29983034type BlockPublicKeyRequest struct {
0 commit comments