mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-05 21:56:50 +00:00

* [NOD-381] Publish transaction messages to MQTT * [NOD-381] Remove redundant variable * [NOD-381] Send payload as string * [NOD-381] Add Error handling * [NOD-381] Respond with TransactionResponse * [NOD-381] Use transactionResponse for notifications * [NOD-381] Move code to appropriate places * [NOD-381] Pass raw block instead of txId * [NOD-381] Add comments to public functions * [NOD-381] Remove print statement * [NOD-381] Pass transaction instead of block; Use pointers so default will be nil; * [NOD-381] Use pointers so value could be nil * [NOD-381] Change variable name * [NOD-381] Set QoS to 2 * [NOD-381] Move isConnected to MQTT, so client won't have to worry about it; General code refactors;
78 lines
1.9 KiB
Go
78 lines
1.9 KiB
Go
package mqtt
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"github.com/daglabs/btcd/apiserver/apimodels"
|
|
"github.com/daglabs/btcd/apiserver/controllers"
|
|
"github.com/daglabs/btcd/btcjson"
|
|
"github.com/jinzhu/gorm"
|
|
)
|
|
|
|
// PublishTransactionsNotifications publishes notification for each transaction of the given block
|
|
func PublishTransactionsNotifications(db *gorm.DB, rawTransactions []btcjson.TxRawResult) error {
|
|
if !isConnected() {
|
|
return nil
|
|
}
|
|
|
|
transactionIds := make([]string, len(rawTransactions))
|
|
for i, tx := range rawTransactions {
|
|
transactionIds[i] = tx.TxID
|
|
}
|
|
|
|
transactions, err := controllers.GetTransactionsByIdsHandler(db, transactionIds)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, transaction := range transactions {
|
|
err = publishTransactionNotifications(transaction)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func publishTransactionNotifications(transaction *apimodels.TransactionResponse) error {
|
|
addresses := uniqueAddressesForTransaction(transaction)
|
|
for _, address := range addresses {
|
|
err := publishTransactionNotificationForAddress(transaction, address)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func uniqueAddressesForTransaction(transaction *apimodels.TransactionResponse) []string {
|
|
addressesMap := make(map[string]struct{})
|
|
addresses := []string{}
|
|
for _, output := range transaction.Outputs {
|
|
if _, exists := addressesMap[output.Address]; !exists {
|
|
addresses = append(addresses, output.Address)
|
|
addressesMap[output.Address] = struct{}{}
|
|
}
|
|
}
|
|
return addresses
|
|
}
|
|
|
|
func publishTransactionNotificationForAddress(transaction *apimodels.TransactionResponse, address string) error {
|
|
payload, err := json.Marshal(transaction)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
token := client.Publish(transactionsTopic(address), 2, false, payload)
|
|
token.Wait()
|
|
if token.Error() != nil {
|
|
return token.Error()
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func transactionsTopic(address string) string {
|
|
return fmt.Sprintf("transactions/%s", address)
|
|
}
|