Skip to content

Commit

Permalink
Refactor transfer-receive in nodeJS library to make it non-blocking
Browse files Browse the repository at this point in the history
  • Loading branch information
ssantos21 committed Jul 11, 2024
1 parent 1841829 commit 76fa200
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 35 deletions.
21 changes: 19 additions & 2 deletions clients/apps/nodejs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ const program = new Command();
const mercurynodejslib = require('mercurynodejslib');
const client_config = require('./client_config');

const sleep = (ms) => {
return new Promise(resolve => setTimeout(resolve, ms));
}

async function main() {

const clientConfig = client_config.load();
Expand Down Expand Up @@ -123,9 +127,22 @@ async function main() {
.argument('<wallet_name>', 'name of the wallet')
.action(async (wallet_name) => {

let received_statechain_ids = await mercurynodejslib.transferReceive(clientConfig, wallet_name);
let receivedStatechainIds = [];

while(true) {

let transferReceiveResult = await mercurynodejslib.transferReceive(clientConfig, wallet_name);
receivedStatechainIds = [...receivedStatechainIds, ...transferReceiveResult.receivedStatechainIds];

if (!transferReceiveResult.isThereBatchLocked) {
console.log("Statecoin batch still locked. Waiting until expiration or unlock.");
await sleep(5000);
} else {
break;
}
}

console.log(JSON.stringify(received_statechain_ids, null, 2));
console.log(JSON.stringify(receivedStatechainIds, null, 2));
});

program.parse();
Expand Down
4 changes: 2 additions & 2 deletions clients/libs/nodejs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,12 @@ const transferReceive = async (clientConfig, walletName) => {

await coin_status.updateCoins(clientConfig, electrumClient, db, walletName);

let received_statechain_ids = await transfer_receive.execute(clientConfig, electrumClient, db, walletName);
let transferReceiveResult = await transfer_receive.execute(clientConfig, electrumClient, db, walletName);

electrumClient.close();
db.close();

return received_statechain_ids;
return transferReceiveResult;
}

module.exports = {
Expand Down
84 changes: 53 additions & 31 deletions clients/libs/nodejs/transfer_receive.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ const execute = async (clientConfig, electrumClient, db, wallet_name) => {
}
}

let isThereBatchLocked = false;
let receivedStatechainIds = [];

let tempCoins = [...wallet.coins];
Expand All @@ -69,10 +70,14 @@ const execute = async (clientConfig, electrumClient, db, wallet_name) => {

if (coin) {
try {
let statechainIdAdded = await processEncryptedMessage(clientConfig, electrumClient, db, coin, encMessage, wallet.network, serverInfo, tempActivities);
let messageResult = await processEncryptedMessage(clientConfig, electrumClient, db, coin, encMessage, wallet.network, serverInfo, tempActivities);

if (statechainIdAdded) {
receivedStatechainIds.push(statechainIdAdded);
if (messageResult.isBatchLocked) {
isThereBatchLocked = true;
}

if (messageResult.statechainId) {
receivedStatechainIds.push(messageResult.statechainId);
}
} catch (error) {
// console.error(`Error: ${error.message}`);
Expand All @@ -84,11 +89,15 @@ const execute = async (clientConfig, electrumClient, db, wallet_name) => {
let newCoin = await mercury_wasm.duplicateCoinToInitializedState(wallet, authPubkey);

if (newCoin) {
let statechainIdAdded = await processEncryptedMessage(clientConfig, electrumClient, db, newCoin, encMessage, wallet.network, serverInfo, tempActivities);
let messageResult = await processEncryptedMessage(clientConfig, electrumClient, db, newCoin, encMessage, wallet.network, serverInfo, tempActivities);

if (statechainIdAdded) {
if (messageResult.isBatchLocked) {
isThereBatchLocked = true;
}

if (messageResult.statechainId) {
tempCoins.push(newCoin);
receivedStatechainIds.push(statechainIdAdded);
receivedStatechainIds.push(messageResult.statechainId);
}
}
} catch (error) {
Expand All @@ -108,7 +117,10 @@ const execute = async (clientConfig, electrumClient, db, wallet_name) => {

await sqlite_manager.updateWallet(db, wallet);

return receivedStatechainIds;
return {
isThereBatchLocked,
receivedStatechainIds
};
}

const getMsgAddr = async (clientConfig, auth_pubkey) => {
Expand Down Expand Up @@ -206,7 +218,16 @@ const processEncryptedMessage = async (clientConfig, electrumClient, db, coin, e
let serverPublicKeyHex = "";

try {
serverPublicKeyHex = await sendTransferReceiverRequestPayload(clientConfig, transferReceiverRequestPayload);
const transferReceiverResult = await sendTransferReceiverRequestPayload(clientConfig, transferReceiverRequestPayload);

if (transferReceiverResult.isBatchLocked) {
return {
isBatchLocked: true,
statechainId: None,
};
}

serverPublicKeyHex = transferReceiverResult.serverPubkey;
} catch (error) {
throw new Error(error);
}
Expand Down Expand Up @@ -237,7 +258,10 @@ const processEncryptedMessage = async (clientConfig, electrumClient, db, coin, e

await sqlite_manager.insertOrUpdateBackupTxs(db, transferMsg.statechain_id, transferMsg.backup_transactions);

return transferMsg.statechain_id;
return {
isBatchLocked: true,
statechainId: transferMsg.statechain_id,
};
}

const getTx0 = async (electrumClient, tx0_txid) => {
Expand Down Expand Up @@ -309,10 +333,6 @@ const unlockStatecoin = async (clientConfig, statechainId, signedStatechainId, a
}
}

const sleep = (ms) => {
return new Promise(resolve => setTimeout(resolve, ms));
}

const sendTransferReceiverRequestPayload = async (clientConfig, transferReceiverRequestPayload) => {

const statechain_entity_url = clientConfig.statechainEntity;
Expand All @@ -327,27 +347,29 @@ const sendTransferReceiverRequestPayload = async (clientConfig, transferReceiver
socksAgent = { httpAgent: new SocksProxyAgent(torProxy) };
}

while(true) {

try {
const response = await axios.post(url, transferReceiverRequestPayload, socksAgent);
return response.data.server_pubkey;
}
catch (error) {

if (error.response.status == 400) {
if (error.response.data.code == 'ExpiredBatchTimeError') {
throw new Error(`Failed to update transfer message ${error.response.data.message}`);
} else if (error.response.data.code == 'StatecoinBatchLockedError') {
console.log("Statecoin batch still locked. Waiting until expiration or unlock.");
await sleep(5000);
continue;
}
} else {
throw new Error(`Failed to update transfer message ${JSON.stringify(error.response.data)}`);
try {
const response = await axios.post(url, transferReceiverRequestPayload, socksAgent);
return {
isBatchLocked: false,
serverPubkey: response.data.server_pubkey,
};
}
catch (error) {

if (error.response.status == 400) {
if (error.response.data.code == 'ExpiredBatchTimeError') {
throw new Error(`Failed to update transfer message ${error.response.data.message}`);
} else if (error.response.data.code == 'StatecoinBatchLockedError') {
return {
isBatchLocked: true,
serverPubkey: null,
};
}
} else {
throw new Error(`Failed to update transfer message ${JSON.stringify(error.response.data)}`);
}
}

}

module.exports = { newTransferAddress, execute };

0 comments on commit 76fa200

Please sign in to comment.