From 62a67b0d66f2bc7b12602e6bca516298aa3a8067 Mon Sep 17 00:00:00 2001 From: Yulexi Matienzo Date: Sun, 15 Mar 2020 23:07:59 +0100 Subject: [PATCH 1/2] adding hash to the subscription object to avoid duplicated subscriptions with mongo --- HISTORY.MD | 4 ++++ logic/observer.js | 18 +++++++++++++++--- logic/storage.js | 15 +++++++++++++++ models/subscription-model.js | 6 ++++++ .../mongodb-storage-provider/index.js | 4 ++++ .../models/subscription-db-model.js | 3 ++- 6 files changed, 46 insertions(+), 4 deletions(-) diff --git a/HISTORY.MD b/HISTORY.MD index 9a0ea71..a84627f 100644 --- a/HISTORY.MD +++ b/HISTORY.MD @@ -1,3 +1,7 @@ +0.4.2 /2020-03-15 +================= +* Updated code to avoid duplicated subscriptions by adding a hash to subscription object + 0.4.2 / 2020-02-16 ================== diff --git a/logic/observer.js b/logic/observer.js index ab4ac2d..3679284 100644 --- a/logic/observer.js +++ b/logic/observer.js @@ -1,4 +1,5 @@ -const errors = require('../util/errors'), + const crypto = require ('crypto') + const errors = require('../util/errors'), TransactionWatcher = require('./transaction-watcher'), Notifier = require('./notifier'), storage = require('./storage'), @@ -38,10 +39,21 @@ class Observer { } subscribe(subscriptionParams, user) { - //TODO: prevent duplicate subscriptions by checking subscription hash (fields "account", "asset_type" etc.) - //https://www.npmjs.com/package/farmhash return this.loadSubscriptions() .then(() => { + // Create hash in the subscription to avoid duplication + + let hashData = `${subscriptionParams.account} ${subscriptionParams.asset_type} ${subscriptionParams.asset_code} ${subscriptionParams.asset_issuer}` + let hash = crypto.createHash('md5').update(hashData).digest("hex"); + subscriptionParams.hash = hash + + let subscription = this.subscriptions.find(s => s.hash == hash) + + if(subscription){ + + return subscription + } + if (this.getActiveSubscriptionsCount() >= config.maxActiveSubscriptions) { return Promise.reject(errors.forbidden('Max active subscriptions exceeded.')) } diff --git a/logic/storage.js b/logic/storage.js index 77e49cc..4367406 100644 --- a/logic/storage.js +++ b/logic/storage.js @@ -58,6 +58,19 @@ class Storage { }) } + /** + * + * @param {*} hash - the hash of the subscription + */ + + async fetchSubscriptioHash(hash){ + this.provider.fetchSubscriptioHash(hash) + .then(subscription =>{ + return subscription + }) + } + + /** * Load next notification from db * @param {*} subscriptionId - subscription id @@ -208,6 +221,8 @@ class Storage { subscription.expires = expirationDate } + subscription.hash = subscriptionParams.hash + return this.provider.saveSubscription(subscription) } diff --git a/models/subscription-model.js b/models/subscription-model.js index 524ee3d..86e35c5 100644 --- a/models/subscription-model.js +++ b/models/subscription-model.js @@ -67,6 +67,12 @@ class SubscriptionModel extends Model { * Cached notifications, associated with the subscription */ notifications + + /** + * Subscription hash to avoid duplicated subscriptions + */ + hash + } module.exports = SubscriptionModel \ No newline at end of file diff --git a/persistence-layer/mongodb-storage-provider/index.js b/persistence-layer/mongodb-storage-provider/index.js index 6bc48e1..0d198c6 100644 --- a/persistence-layer/mongodb-storage-provider/index.js +++ b/persistence-layer/mongodb-storage-provider/index.js @@ -41,6 +41,10 @@ class MongoDBStorageProvider extends StorageProvider { return Subscription.findById(id) } + fetchSubscriptioHash(hash){ + return Subscription.findOne({hash}) + } + fetchNextNotification(subscriptionId) { return Notification.findOne({subscriptions: toObjectId(subscriptionId)}) } diff --git a/persistence-layer/mongodb-storage-provider/models/subscription-db-model.js b/persistence-layer/mongodb-storage-provider/models/subscription-db-model.js index c80d336..29d48d6 100644 --- a/persistence-layer/mongodb-storage-provider/models/subscription-db-model.js +++ b/persistence-layer/mongodb-storage-provider/models/subscription-db-model.js @@ -13,7 +13,8 @@ const subscriptionSchema = new Schema({ reaction_url: {type: String}, delivery_failures: {type: Number, default: 0}, sent: {type: Number, default: 0}, - expires: {type: Date} + expires: {type: Date}, + hash:{type:String} }, { timestamps: {createdAt: 'created', updatedAt: 'updated'} From e99a4148a33b2e3a022d46f9330cd4d4b4d3ba9a Mon Sep 17 00:00:00 2001 From: Yulexi Matienzo Date: Wed, 18 Mar 2020 00:19:19 +0100 Subject: [PATCH 2/2] Updated code to avoid duplicated subscriptions by adding a hash to subscription object --- HISTORY.MD | 2 +- logic/observer.js | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/HISTORY.MD b/HISTORY.MD index a84627f..25a9133 100644 --- a/HISTORY.MD +++ b/HISTORY.MD @@ -1,4 +1,4 @@ -0.4.2 /2020-03-15 +0.4.3 /2020-03-17 ================= * Updated code to avoid duplicated subscriptions by adding a hash to subscription object diff --git a/logic/observer.js b/logic/observer.js index 3679284..6e7c53b 100644 --- a/logic/observer.js +++ b/logic/observer.js @@ -43,8 +43,8 @@ class Observer { .then(() => { // Create hash in the subscription to avoid duplication - let hashData = `${subscriptionParams.account} ${subscriptionParams.asset_type} ${subscriptionParams.asset_code} ${subscriptionParams.asset_issuer}` - let hash = crypto.createHash('md5').update(hashData).digest("hex"); + let hashData = `${subscriptionParams.reaction_url} ${subscriptionParams.account} ${subscriptionParams.memo} ${subscriptionParams.operation_types} ${subscriptionParams.asset_code} ${subscriptionParams.asset_issuer} ${subscriptionParams.expires}` + let hash = crypto.createHash('md5').update(hashData).digest("hex").toString(); subscriptionParams.hash = hash let subscription = this.subscriptions.find(s => s.hash == hash) diff --git a/package.json b/package.json index abb6b43..4cbd53c 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@stellar-expert/operations-notifier", "license": "MIT", "private": true, - "version": "0.4.2", + "version": "0.4.3", "author": "orbitlens", "description": "Stellar operations observer and notifier.", "main": "app.js",