diff --git a/cmd/run.go b/cmd/run.go index f8e707a0..bece8e51 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -49,7 +49,9 @@ func init() { runCmd.PersistentFlags().Uint64("api-port", 0, "When set, determines the port on which this node will listen for json "+ "requests. If unset, the port will default to what is present in the DeSoParams set.") - + runCmd.PersistentFlags().String("amm-metadata-public-key", "", + "The base58-encoded public key for the AMM_METADATA user, which is "+ + "used to set the trading fees on users' coins.") // Onboarding runCmd.PersistentFlags().String("starter-deso-seed", "", "Send a small amount of DeSo from this seed to new users.") diff --git a/routes/user.go b/routes/user.go index 16d38542..9ae4a295 100644 --- a/routes/user.go +++ b/routes/user.go @@ -2398,7 +2398,7 @@ func (fes *APIServer) GetNotifications(ww http.ResponseWriter, req *http.Request PostsByHash: postEntryResponses, LastSeenIndex: lastSeenIndex, } - if err := json.NewEncoder(ww).Encode(res); err != nil { + if err = json.NewEncoder(ww).Encode(res); err != nil { _AddBadRequestError(ww, fmt.Sprintf( "GetNotifications: Problem encoding response as JSON: %v", err)) return @@ -2520,38 +2520,46 @@ func (fes *APIServer) _getDBNotifications(request *GetNotificationsRequest, bloc // In this case we need to look up the full transaction and convert // it into a proper transaction response. - txnMeta := lib.DbGetTxindexTransactionRefByTxID(fes.TXIndex.TXIndexChain.DB(), nil, txID) - if txnMeta == nil { + dbTxnMeta := lib.DbGetTxindexTransactionRefByTxID(fes.TXIndex.TXIndexChain.DB(), nil, txID) + if dbTxnMeta == nil { // We should never be missing a transaction for a given txid, but // just continue in this case. glog.Errorf("GetNotifications: Missing TransactionMetadata for txid %v", txID) continue } - // Skip transactions that aren't notifications - if !TxnMetaIsNotification(txnMeta, request.PublicKeyBase58Check, utxoView) { - continue + txnMetas := []*lib.TransactionMetadata{dbTxnMeta} + if dbTxnMeta.AtomicTxnsWrapperTxindexMetadata != nil { + // If this is an atomic transaction, we need to iterate over the inner transactions + // and convert them into TransactionMetadata objects. + txnMetas = dbTxnMeta.AtomicTxnsWrapperTxindexMetadata.InnerTxnsTransactionMetadata } - transactorPkBytes, _, err := lib.Base58CheckDecode(txnMeta.TransactorPublicKeyBase58Check) - if err != nil { - glog.Errorf("GetNotifications: unable to decode public key %v", txnMeta.TransactorPublicKeyBase58Check) - continue - } - // Skip transactions from blocked users. - if _, ok := blockedPubKeys[lib.PkToString(transactorPkBytes, fes.Params)]; ok { - continue - } - // Skip transactions from blacklisted public keys - transactorPKID := utxoView.GetPKIDForPublicKey(transactorPkBytes) - if transactorPKID == nil || fes.IsUserBlacklisted(transactorPKID.PKID, utxoView) { - continue - } - currentIndexBytes := keysFound[ii][len(lib.DbTxindexPublicKeyPrefix(pkBytes)):] - res := &TransactionMetadataResponse{ - Metadata: txnMeta, - Index: int64(lib.DecodeUint32(currentIndexBytes)), - } - if NotificationTxnShouldBeIncluded(res.Metadata, &filteredOutCategories) { - dbTxnMetadataFound = append(dbTxnMetadataFound, res) + for _, txnMeta := range txnMetas { + // Skip transactions that aren't notifications + if !TxnMetaIsNotification(txnMeta, request.PublicKeyBase58Check, utxoView) { + continue + } + transactorPkBytes, _, err := lib.Base58CheckDecode(txnMeta.TransactorPublicKeyBase58Check) + if err != nil { + glog.Errorf("GetNotifications: unable to decode public key %v", txnMeta.TransactorPublicKeyBase58Check) + continue + } + // Skip transactions from blocked users. + if _, ok := blockedPubKeys[lib.PkToString(transactorPkBytes, fes.Params)]; ok { + continue + } + // Skip transactions from blacklisted public keys + transactorPKID := utxoView.GetPKIDForPublicKey(transactorPkBytes) + if transactorPKID == nil || fes.IsUserBlacklisted(transactorPKID.PKID, utxoView) { + continue + } + currentIndexBytes := keysFound[ii][len(lib.DbTxindexPublicKeyPrefix(pkBytes)):] + res := &TransactionMetadataResponse{ + Metadata: txnMeta, + Index: int64(lib.DecodeUint32(currentIndexBytes)), + } + if NotificationTxnShouldBeIncluded(res.Metadata, &filteredOutCategories) { + dbTxnMetadataFound = append(dbTxnMetadataFound, res) + } } } @@ -2625,51 +2633,60 @@ func (fes *APIServer) _getMempoolNotifications(request *GetNotificationsRequest, mempoolTxnMetadata := []*TransactionMetadataResponse{} for _, poolTx := range poolTxns { - txnMeta := poolTx.TxMeta - if txnMeta == nil { + poolTxnMeta := poolTx.TxMeta + if poolTxnMeta == nil { continue } // Set the current index we will use to identify this transaction. currentIndex := NextIndex - // Increment the NextIndex if this transaction is associated with the user's - // public key in any way. This is what the db would do when storing it, and so - // this treatment should be consistent. - if TxnIsAssociatedWithPublicKey(txnMeta, request.PublicKeyBase58Check) { - NextIndex++ + txnMetas := []*lib.TransactionMetadata{poolTxnMeta} + if poolTxnMeta.AtomicTxnsWrapperTxindexMetadata != nil { + // If this is an atomic transaction, we need to iterate over the inner transactions + // and convert them into TransactionMetadata objects. + txnMetas = poolTxnMeta.AtomicTxnsWrapperTxindexMetadata.InnerTxnsTransactionMetadata } + for _, txnMeta := range txnMetas { - // If the transaction is a notification then add it to our list with the proper - // index value if the transactor is not a blocked public key - if TxnMetaIsNotification(txnMeta, request.PublicKeyBase58Check, utxoView) { - transactorPkBytes, _, err := lib.Base58CheckDecode(txnMeta.TransactorPublicKeyBase58Check) - if err != nil { - glog.Errorf("GetNotifications: unable to decode public key %v", txnMeta.TransactorPublicKeyBase58Check) - continue + // Increment the NextIndex if this transaction is associated with the user's + // public key in any way. This is what the db would do when storing it, and so + // this treatment should be consistent. + if TxnIsAssociatedWithPublicKey(txnMeta, request.PublicKeyBase58Check) { + NextIndex++ } - // Skip transactions from blocked users. - if _, ok := blockedPubKeys[lib.PkToString(transactorPkBytes, fes.Params)]; ok { - continue - } - // Skip blacklisted public keys - transactorPKID := utxoView.GetPKIDForPublicKey(transactorPkBytes) - if transactorPKID == nil || fes.IsUserBlacklisted(transactorPKID.PKID, utxoView) { - continue - } + // If the transaction is a notification then add it to our list with the proper + // index value if the transactor is not a blocked public key + if TxnMetaIsNotification(txnMeta, request.PublicKeyBase58Check, utxoView) { + transactorPkBytes, _, err := lib.Base58CheckDecode(txnMeta.TransactorPublicKeyBase58Check) + if err != nil { + glog.Errorf("GetNotifications: unable to decode public key %v", txnMeta.TransactorPublicKeyBase58Check) + continue + } - // Skip transactions when notification should not be included based on filter - if !NotificationTxnShouldBeIncluded(txnMeta, &filteredOutCategories) { - continue - } + // Skip transactions from blocked users. + if _, ok := blockedPubKeys[lib.PkToString(transactorPkBytes, fes.Params)]; ok { + continue + } + // Skip blacklisted public keys + transactorPKID := utxoView.GetPKIDForPublicKey(transactorPkBytes) + if transactorPKID == nil || fes.IsUserBlacklisted(transactorPKID.PKID, utxoView) { + continue + } - // Only include transactions that occur on or after the start index, if defined - if request.FetchStartIndex < 0 || (request.FetchStartIndex >= currentIndex && iterateReverse) || (request.FetchStartIndex <= currentIndex && !iterateReverse) { - mempoolTxnMetadata = append(mempoolTxnMetadata, &TransactionMetadataResponse{ - Metadata: txnMeta, - Index: currentIndex, - }) + // Skip transactions when notification should not be included based on filter + if !NotificationTxnShouldBeIncluded(txnMeta, &filteredOutCategories) { + continue + } + + // Only include transactions that occur on or after the start index, if defined + if request.FetchStartIndex < 0 || (request.FetchStartIndex >= currentIndex && iterateReverse) || (request.FetchStartIndex <= currentIndex && !iterateReverse) { + mempoolTxnMetadata = append(mempoolTxnMetadata, &TransactionMetadataResponse{ + Metadata: txnMeta, + Index: currentIndex, + }) + } } }