diff --git a/src/controllers/wallet/atomic-swap/tx-proposal.controller.js b/src/controllers/wallet/atomic-swap/tx-proposal.controller.js index 62966315..f87fa228 100644 --- a/src/controllers/wallet/atomic-swap/tx-proposal.controller.js +++ b/src/controllers/wallet/atomic-swap/tx-proposal.controller.js @@ -16,11 +16,11 @@ const { } = require('@hathor/wallet-lib'); const atomicSwapService = require('../../../services/atomic-swap.service'); const { parametersValidation } = require('../../../helpers/validations.helper'); -const { lock, lockTypes } = require('../../../lock'); +const { lockTypes } = require('../../../lock'); const { mapTxReturn, runSendTransaction } = require('../../../helpers/tx.helper'); const constants = require('../../../constants'); const { removeListenedProposal } = require('../../../services/atomic-swap.service'); -const { lockSendTx } = require('../../../helpers/lock.helper'); +const { lockSendTx, getWalletLock } = require('../../../helpers/lock.helper'); const { cantSendTxErrorMessage } = require('../../../helpers/constants'); /** @@ -407,7 +407,7 @@ async function unlockInputs(req, res) { return; } - const canStart = lock.get(req.walletId).lock(lockTypes.SEND_TX); + const canStart = getWalletLock(req.walletId).lock(lockTypes.SEND_TX); if (!canStart) { res.send({ success: false, error: 'Cannot run this method while a transaction is being sent.' }); return; @@ -427,7 +427,7 @@ async function unlockInputs(req, res) { } catch (err) { res.send({ success: false, error: err.message }); } finally { - lock.get(req.walletId).unlock(lockTypes.SEND_TX); + getWalletLock(req.walletId).unlock(lockTypes.SEND_TX); } } diff --git a/src/helpers/lock.helper.js b/src/helpers/lock.helper.js index bd03aa15..56e3cbdc 100644 --- a/src/helpers/lock.helper.js +++ b/src/helpers/lock.helper.js @@ -6,6 +6,19 @@ */ const { lock, lockTypes } = require('../lock'); +const { hsmWalletIds } = require('../services/wallets.service'); + +/** + * Get the Lock instance for the given walletID. + * @param {string} walletId + */ +function getWalletLock(walletId) { + if (hsmWalletIds.has(walletId)) { + // This is an HSM wallet and the walletLock should be global. + return lock.hsmLock; + } + return lock.get(walletId); +} /** * Acquire the SEND_TX lock for a wallet and return the method to unlock it. @@ -15,7 +28,8 @@ const { lock, lockTypes } = require('../lock'); * */ function lockSendTx(walletId) { - const walletLock = lock.get(walletId); + const walletLock = getWalletLock(walletId); + const canStart = walletLock.lock(lockTypes.SEND_TX); if (!canStart) { return null; @@ -34,4 +48,5 @@ function lockSendTx(walletId) { module.exports = { lockSendTx, + getWalletLock, }; diff --git a/src/lock.js b/src/lock.js index d011b9a8..27a00332 100644 --- a/src/lock.js +++ b/src/lock.js @@ -78,6 +78,9 @@ class GlobalLock { // This is the global lock since some methods are required to be // running only once across all wallets. this.globalLock = new Lock(); + // HSM wallets need to share the same send-tx lock because the SDK does not + // allow 2 open connections at the same time. + this._hsmLock = new Lock(); } delete(walletId) { @@ -103,6 +106,10 @@ class GlobalLock { unlock(type) { this.globalLock.unlock(type); } + + get hsmLock() { + return this._hsmLock; + } } export const lock = new GlobalLock();