capitalisk-dex 17.3.0 → 18.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/defaults/config.js +2 -2
- package/index.js +290 -289
- package/package.json +1 -1
package/defaults/config.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
module.exports = {
|
|
2
2
|
passiveMode: false,
|
|
3
3
|
priceDecimalPrecision: null,
|
|
4
|
-
initRetryDelay:
|
|
4
|
+
initRetryDelay: 20000,
|
|
5
5
|
multisigExpiry: 86400000,
|
|
6
6
|
multisigExpiryCheckInterval: 60000,
|
|
7
7
|
multisigFlushInterval: 15000,
|
|
8
|
-
multisigReadyDelay:
|
|
8
|
+
multisigReadyDelay: 15000,
|
|
9
9
|
multisigMaxBatchSize: 25,
|
|
10
10
|
multisigRetryInterval: 60000,
|
|
11
11
|
recentTransfersExpiry: 1800000,
|
package/index.js
CHANGED
|
@@ -21,7 +21,7 @@ const { CAPITALISK_DEX_PASSWORD } = process.env;
|
|
|
21
21
|
const CIPHER_ALGORITHM = 'aes-192-cbc';
|
|
22
22
|
const CIPHER_KEY = CAPITALISK_DEX_PASSWORD ? crypto.scryptSync(CAPITALISK_DEX_PASSWORD, 'salt', 24) : undefined;
|
|
23
23
|
const CIPHER_IV = Buffer.alloc(16, 0);
|
|
24
|
-
const DEFAULT_INIT_RETRY_DELAY =
|
|
24
|
+
const DEFAULT_INIT_RETRY_DELAY = 20000;
|
|
25
25
|
const DEFAULT_MULTISIG_READY_DELAY = 5000;
|
|
26
26
|
const DEFAULT_MULTISIG_RETRY_INTERVAL = 60000;
|
|
27
27
|
const DEFAULT_SIGNATURE_READY_DELAY = 10000;
|
|
@@ -95,6 +95,7 @@ module.exports = class CapitaliskDEXModule {
|
|
|
95
95
|
this.isQuoteChainForked = false;
|
|
96
96
|
this.lastSnapshot = null;
|
|
97
97
|
this.finalizedSnapshot = null;
|
|
98
|
+
this.scheduledTransferInfos = [];
|
|
98
99
|
this.pendingTransfers = new Map();
|
|
99
100
|
this.chainSymbols.forEach((chainSymbol) => {
|
|
100
101
|
this.multisigWalletInfo[chainSymbol] = {
|
|
@@ -1203,7 +1204,7 @@ module.exports = class CapitaliskDEXModule {
|
|
|
1203
1204
|
`Failed to load initial snapshot because of error: ${error.message} - DEX node will start with an empty order book`
|
|
1204
1205
|
);
|
|
1205
1206
|
|
|
1206
|
-
while (
|
|
1207
|
+
while (true) {
|
|
1207
1208
|
try {
|
|
1208
1209
|
let [baseMaxHeight, quoteMaxHeight] = await Promise.all([
|
|
1209
1210
|
this._getMaxBlockHeight(this.baseChainSymbol, false),
|
|
@@ -1216,31 +1217,37 @@ module.exports = class CapitaliskDEXModule {
|
|
|
1216
1217
|
this.logger.error(`The ${this.quoteChainSymbol} chain had a height of 0`);
|
|
1217
1218
|
}
|
|
1218
1219
|
if (!baseMaxHeight || !quoteMaxHeight) {
|
|
1219
|
-
|
|
1220
|
-
await wait(this.initRetryDelay);
|
|
1221
|
-
continue;
|
|
1220
|
+
throw new Error('Invalid chain heights');
|
|
1222
1221
|
}
|
|
1223
1222
|
this.processedHeights[this.baseChainSymbol] = baseMaxHeight;
|
|
1224
1223
|
this.processedHeights[this.quoteChainSymbol] = quoteMaxHeight;
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1224
|
+
break;
|
|
1225
|
+
} catch (initHeightError) {
|
|
1226
|
+
this.logger.error(
|
|
1227
|
+
`Failed to initialize last processed heights because of error: ${initHeightError.message}`
|
|
1228
1228
|
);
|
|
1229
|
+
this.logger.debug('Retrying initialization of last processed heights...');
|
|
1230
|
+
await wait(this.initRetryDelay);
|
|
1229
1231
|
}
|
|
1230
1232
|
}
|
|
1231
1233
|
}
|
|
1232
1234
|
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1235
|
+
while (true) {
|
|
1236
|
+
try {
|
|
1237
|
+
let [baseChainMaxBlock, quoteChainMaxBlock] = await Promise.all([
|
|
1238
|
+
this._getBlockAtHeight(this.baseChainSymbol, this.processedHeights[this.baseChainSymbol]),
|
|
1239
|
+
this._getBlockAtHeight(this.quoteChainSymbol, this.processedHeights[this.quoteChainSymbol])
|
|
1240
|
+
]);
|
|
1241
|
+
this.lastProcessedBlocks[this.baseChainSymbol] = baseChainMaxBlock;
|
|
1242
|
+
this.lastProcessedBlocks[this.quoteChainSymbol] = quoteChainMaxBlock;
|
|
1243
|
+
break;
|
|
1244
|
+
} catch (error) {
|
|
1245
|
+
this.logger.error(
|
|
1246
|
+
`Failed to initialize last processed blocks because of error: ${error.message}`
|
|
1247
|
+
);
|
|
1248
|
+
this.logger.debug('Retrying initialization of last processed blocks...');
|
|
1249
|
+
await wait(this.initRetryDelay);
|
|
1250
|
+
}
|
|
1244
1251
|
}
|
|
1245
1252
|
|
|
1246
1253
|
await Promise.all(
|
|
@@ -1436,23 +1443,17 @@ module.exports = class CapitaliskDEXModule {
|
|
|
1436
1443
|
) {
|
|
1437
1444
|
let currentOrderBook = this.tradeEngine.getSnapshot();
|
|
1438
1445
|
this.tradeEngine.clear();
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
);
|
|
1451
|
-
} catch (error) {
|
|
1452
|
-
this.logger.error(
|
|
1453
|
-
`Failed to refund the order book according to config because of error: ${error.message}`
|
|
1454
|
-
);
|
|
1455
|
-
}
|
|
1446
|
+
this.scheduleRefundOrderBook(
|
|
1447
|
+
{
|
|
1448
|
+
orderBook: currentOrderBook,
|
|
1449
|
+
chainHeights: {...latestChainHeights}
|
|
1450
|
+
},
|
|
1451
|
+
latestBlockTimestamp,
|
|
1452
|
+
{
|
|
1453
|
+
[this.baseChainSymbol]: this.options.chains[this.baseChainSymbol].dexMovedToAddress,
|
|
1454
|
+
[this.quoteChainSymbol]: this.options.chains[this.quoteChainSymbol].dexMovedToAddress
|
|
1455
|
+
}
|
|
1456
|
+
);
|
|
1456
1457
|
}
|
|
1457
1458
|
}
|
|
1458
1459
|
|
|
@@ -1726,103 +1727,93 @@ module.exports = class CapitaliskDEXModule {
|
|
|
1726
1727
|
let disabledOrders = orders.filter(orderTxn => orderTxn.type === 'disabled');
|
|
1727
1728
|
|
|
1728
1729
|
if (!this.passiveMode) {
|
|
1729
|
-
movedOrders.forEach(
|
|
1730
|
+
movedOrders.forEach((orderTxn) => {
|
|
1730
1731
|
let protocolMessage = this._computeProtocolMessage(orderTxn.sourceChain, 'r5', [orderTxn.id, orderTxn.movedToAddress], 'DEX has moved');
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
);
|
|
1745
|
-
}
|
|
1732
|
+
this.scheduleRefundTransaction(
|
|
1733
|
+
orderTxn,
|
|
1734
|
+
latestBlockTimestamp,
|
|
1735
|
+
protocolMessage,
|
|
1736
|
+
{type: 'r5', originOrderId: orderTxn.id},
|
|
1737
|
+
`Chain ${chainSymbol}: Failed to post multisig refund transaction for moved DEX order ID ${
|
|
1738
|
+
orderTxn.id
|
|
1739
|
+
} to ${
|
|
1740
|
+
orderTxn.sourceWalletAddress
|
|
1741
|
+
} on chain ${
|
|
1742
|
+
orderTxn.sourceChain
|
|
1743
|
+
}`
|
|
1744
|
+
);
|
|
1746
1745
|
});
|
|
1747
1746
|
|
|
1748
|
-
disabledOrders.forEach(
|
|
1747
|
+
disabledOrders.forEach((orderTxn) => {
|
|
1749
1748
|
let protocolMessage = this._computeProtocolMessage(orderTxn.sourceChain, 'r6', [orderTxn.id], 'DEX has been disabled');
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
);
|
|
1764
|
-
}
|
|
1749
|
+
this.scheduleRefundTransaction(
|
|
1750
|
+
orderTxn,
|
|
1751
|
+
latestBlockTimestamp,
|
|
1752
|
+
protocolMessage,
|
|
1753
|
+
{type: 'r6', originOrderId: orderTxn.id},
|
|
1754
|
+
`Chain ${chainSymbol}: Failed to post multisig refund transaction for disabled DEX order ID ${
|
|
1755
|
+
orderTxn.id
|
|
1756
|
+
} to ${
|
|
1757
|
+
orderTxn.sourceWalletAddress
|
|
1758
|
+
} on chain ${
|
|
1759
|
+
orderTxn.sourceChain
|
|
1760
|
+
}`
|
|
1761
|
+
);
|
|
1765
1762
|
});
|
|
1766
1763
|
|
|
1767
|
-
invalidOrders.forEach(
|
|
1764
|
+
invalidOrders.forEach((orderTxn) => {
|
|
1768
1765
|
let reasonMessage = 'Invalid order';
|
|
1769
1766
|
if (orderTxn.reason) {
|
|
1770
1767
|
reasonMessage += ` - ${orderTxn.reason}`;
|
|
1771
1768
|
}
|
|
1772
1769
|
let protocolMessage = this._computeProtocolMessage(orderTxn.sourceChain, 'r1', [orderTxn.id], reasonMessage);
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
);
|
|
1787
|
-
}
|
|
1770
|
+
this.scheduleRefundTransaction(
|
|
1771
|
+
orderTxn,
|
|
1772
|
+
latestBlockTimestamp,
|
|
1773
|
+
protocolMessage,
|
|
1774
|
+
{type: 'r1', originOrderId: orderTxn.id},
|
|
1775
|
+
`Chain ${chainSymbol}: Failed to post multisig refund transaction for invalid order ID ${
|
|
1776
|
+
orderTxn.id
|
|
1777
|
+
} to ${
|
|
1778
|
+
orderTxn.sourceWalletAddress
|
|
1779
|
+
} on chain ${
|
|
1780
|
+
orderTxn.sourceChain
|
|
1781
|
+
}`
|
|
1782
|
+
);
|
|
1788
1783
|
});
|
|
1789
1784
|
|
|
1790
|
-
oversizedOrders.forEach(
|
|
1785
|
+
oversizedOrders.forEach((orderTxn) => {
|
|
1791
1786
|
let protocolMessage = this._computeProtocolMessage(orderTxn.sourceChain, 'r1', [orderTxn.id], 'Oversized order');
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
);
|
|
1806
|
-
}
|
|
1787
|
+
this.scheduleRefundTransaction(
|
|
1788
|
+
orderTxn,
|
|
1789
|
+
latestBlockTimestamp,
|
|
1790
|
+
protocolMessage,
|
|
1791
|
+
{type: 'r1', originOrderId: orderTxn.id},
|
|
1792
|
+
`Chain ${chainSymbol}: Failed to post multisig refund transaction for oversized order ID ${
|
|
1793
|
+
orderTxn.id
|
|
1794
|
+
} to ${
|
|
1795
|
+
orderTxn.sourceWalletAddress
|
|
1796
|
+
} on chain ${
|
|
1797
|
+
orderTxn.sourceChain
|
|
1798
|
+
}`
|
|
1799
|
+
);
|
|
1807
1800
|
});
|
|
1808
1801
|
|
|
1809
|
-
undersizedOrders.forEach(
|
|
1802
|
+
undersizedOrders.forEach((orderTxn) => {
|
|
1810
1803
|
let protocolMessage = this._computeProtocolMessage(orderTxn.sourceChain, 'r1', [orderTxn.id], 'Undersized order');
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
);
|
|
1825
|
-
}
|
|
1804
|
+
this.scheduleRefundTransaction(
|
|
1805
|
+
orderTxn,
|
|
1806
|
+
latestBlockTimestamp,
|
|
1807
|
+
protocolMessage,
|
|
1808
|
+
{type: 'r1', originOrderId: orderTxn.id},
|
|
1809
|
+
`Chain ${chainSymbol}: Failed to post multisig refund transaction for undersized order ID ${
|
|
1810
|
+
orderTxn.id
|
|
1811
|
+
} to ${
|
|
1812
|
+
orderTxn.sourceWalletAddress
|
|
1813
|
+
} on chain ${
|
|
1814
|
+
orderTxn.sourceChain
|
|
1815
|
+
}`
|
|
1816
|
+
);
|
|
1826
1817
|
});
|
|
1827
1818
|
}
|
|
1828
1819
|
|
|
@@ -1832,7 +1823,7 @@ module.exports = class CapitaliskDEXModule {
|
|
|
1832
1823
|
} else {
|
|
1833
1824
|
expiredOrders = this.tradeEngine.expireAskOrders(chainHeight);
|
|
1834
1825
|
}
|
|
1835
|
-
expiredOrders.forEach(
|
|
1826
|
+
expiredOrders.forEach((expiredOrder) => {
|
|
1836
1827
|
this.logger.info(
|
|
1837
1828
|
`Chain ${chainSymbol}: Order ${expiredOrder.id} at height ${expiredOrder.height} expired`
|
|
1838
1829
|
);
|
|
@@ -1840,30 +1831,23 @@ module.exports = class CapitaliskDEXModule {
|
|
|
1840
1831
|
return;
|
|
1841
1832
|
}
|
|
1842
1833
|
let protocolMessage = this._computeProtocolMessage(expiredOrder.sourceChain, 'r2', [expiredOrder.id], 'Expired order');
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
} on chain ${
|
|
1858
|
-
expiredOrder.sourceChain
|
|
1859
|
-
} because of error: ${
|
|
1860
|
-
error.message
|
|
1861
|
-
}`
|
|
1862
|
-
);
|
|
1863
|
-
}
|
|
1834
|
+
this.scheduleRefundOrder(
|
|
1835
|
+
expiredOrder,
|
|
1836
|
+
latestBlockTimestamp,
|
|
1837
|
+
expiredOrder.expiryHeight,
|
|
1838
|
+
protocolMessage,
|
|
1839
|
+
{type: 'r2', originOrderId: expiredOrder.id},
|
|
1840
|
+
`Chain ${chainSymbol}: Failed to post multisig refund transaction for expired order ID ${
|
|
1841
|
+
expiredOrder.id
|
|
1842
|
+
} to ${
|
|
1843
|
+
expiredOrder.sourceWalletAddress
|
|
1844
|
+
} on chain ${
|
|
1845
|
+
expiredOrder.sourceChain
|
|
1846
|
+
}`
|
|
1847
|
+
);
|
|
1864
1848
|
});
|
|
1865
1849
|
|
|
1866
|
-
closeOrders.forEach(
|
|
1850
|
+
closeOrders.forEach((orderTxn) => {
|
|
1867
1851
|
let targetOrder = this.tradeEngine.getOrder(orderTxn.orderIdToClose);
|
|
1868
1852
|
if (!targetOrder) {
|
|
1869
1853
|
this.logger.warn(
|
|
@@ -1895,29 +1879,22 @@ module.exports = class CapitaliskDEXModule {
|
|
|
1895
1879
|
return;
|
|
1896
1880
|
}
|
|
1897
1881
|
let protocolMessage = this._computeProtocolMessage(refundTxn.sourceChain, 'r3', [targetOrder.id, orderTxn.id], 'Closed order');
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
} on chain ${
|
|
1912
|
-
targetOrder.sourceChain
|
|
1913
|
-
} because of error: ${
|
|
1914
|
-
error.message
|
|
1915
|
-
}`
|
|
1916
|
-
);
|
|
1917
|
-
}
|
|
1882
|
+
this.scheduleRefundTransaction(
|
|
1883
|
+
refundTxn,
|
|
1884
|
+
latestBlockTimestamp,
|
|
1885
|
+
protocolMessage,
|
|
1886
|
+
{type: 'r3', originOrderId: targetOrder.id, closerOrderId: orderTxn.id},
|
|
1887
|
+
`Chain ${chainSymbol}: Failed to post multisig refund transaction for closed order ID ${
|
|
1888
|
+
targetOrder.id
|
|
1889
|
+
} to ${
|
|
1890
|
+
targetOrder.sourceWalletAddress
|
|
1891
|
+
} on chain ${
|
|
1892
|
+
targetOrder.sourceChain
|
|
1893
|
+
}`
|
|
1894
|
+
);
|
|
1918
1895
|
});
|
|
1919
1896
|
|
|
1920
|
-
limitAndMarketOrders.forEach(
|
|
1897
|
+
limitAndMarketOrders.forEach((orderTxn) => {
|
|
1921
1898
|
let result;
|
|
1922
1899
|
try {
|
|
1923
1900
|
result = this.tradeEngine.addOrder(orderTxn);
|
|
@@ -1944,7 +1921,7 @@ module.exports = class CapitaliskDEXModule {
|
|
|
1944
1921
|
|
|
1945
1922
|
let makerCount = 0;
|
|
1946
1923
|
|
|
1947
|
-
result.makers.forEach(
|
|
1924
|
+
result.makers.forEach((makerOrder) => {
|
|
1948
1925
|
let makerChainOptions = this.options.chains[makerOrder.targetChain];
|
|
1949
1926
|
let makerAddress = makerOrder.targetWalletAddress;
|
|
1950
1927
|
let makerAmount = makerOrder.targetChain === this.baseChainSymbol ? makerOrder.lastValueTaken : makerOrder.lastSizeTaken;
|
|
@@ -1973,84 +1950,76 @@ module.exports = class CapitaliskDEXModule {
|
|
|
1973
1950
|
[makerOrder.sourceChain, makerOrder.id, result.taker.id],
|
|
1974
1951
|
'Order made'
|
|
1975
1952
|
);
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
} catch (error) {
|
|
1984
|
-
this.logger.error(
|
|
1985
|
-
`Chain ${chainSymbol}: Failed to post multisig transaction of maker ${makerAddress} on chain ${makerOrder.targetChain} because of error: ${error.message}`
|
|
1986
|
-
);
|
|
1987
|
-
}
|
|
1953
|
+
this.scheduleMultisigTransaction(
|
|
1954
|
+
makerOrder.targetChain,
|
|
1955
|
+
makerTxn,
|
|
1956
|
+
protocolMessage,
|
|
1957
|
+
{type: 't2', originOrderId: makerOrder.id, makerOrderId: makerOrder.id, takerOrderId: result.taker.id},
|
|
1958
|
+
`Chain ${chainSymbol}: Failed to post multisig transaction of maker ${makerAddress} on chain ${makerOrder.targetChain}`
|
|
1959
|
+
);
|
|
1988
1960
|
});
|
|
1989
1961
|
|
|
1990
|
-
|
|
1991
|
-
if (
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1962
|
+
if (makerCount) {
|
|
1963
|
+
if (takerAmount > 0n) {
|
|
1964
|
+
let takerTxn = {
|
|
1965
|
+
recipientAddress: takerAddress,
|
|
1966
|
+
amount: takerAmount.toString(),
|
|
1967
|
+
fee: takerChainOptions.exchangeFeeBase.toString(),
|
|
1968
|
+
timestamp: latestBlockTimestamp,
|
|
1969
|
+
height: latestChainHeights[takerTargetChain]
|
|
1970
|
+
};
|
|
1971
|
+
let protocolMessage = this._computeProtocolMessage(
|
|
1972
|
+
takerTargetChain,
|
|
1973
|
+
't1',
|
|
1974
|
+
[result.taker.sourceChain, result.taker.id, makerCount],
|
|
1975
|
+
'Orders taken'
|
|
1997
1976
|
);
|
|
1998
|
-
|
|
1999
|
-
}
|
|
2000
|
-
let takerTxn = {
|
|
2001
|
-
recipientAddress: takerAddress,
|
|
2002
|
-
amount: takerAmount.toString(),
|
|
2003
|
-
fee: takerChainOptions.exchangeFeeBase.toString(),
|
|
2004
|
-
timestamp: latestBlockTimestamp,
|
|
2005
|
-
height: latestChainHeights[takerTargetChain]
|
|
2006
|
-
};
|
|
2007
|
-
let protocolMessage = this._computeProtocolMessage(
|
|
2008
|
-
takerTargetChain,
|
|
2009
|
-
't1',
|
|
2010
|
-
[result.taker.sourceChain, result.taker.id, makerCount],
|
|
2011
|
-
'Orders taken'
|
|
2012
|
-
);
|
|
2013
|
-
try {
|
|
2014
|
-
await this.execMultisigTransaction(
|
|
1977
|
+
this.scheduleMultisigTransaction(
|
|
2015
1978
|
takerTargetChain,
|
|
2016
1979
|
takerTxn,
|
|
2017
1980
|
protocolMessage,
|
|
2018
|
-
{type: 't1', originOrderId: result.taker.id, takerOrderId: result.taker.id, makerCount}
|
|
1981
|
+
{type: 't1', originOrderId: result.taker.id, takerOrderId: result.taker.id, makerCount},
|
|
1982
|
+
`Chain ${chainSymbol}: Failed to post multisig transaction of taker ${takerAddress} on chain ${takerTargetChain}`
|
|
2019
1983
|
);
|
|
2020
|
-
}
|
|
2021
|
-
this.logger.
|
|
2022
|
-
`Chain ${chainSymbol}:
|
|
1984
|
+
} else {
|
|
1985
|
+
this.logger.warn(
|
|
1986
|
+
`Chain ${chainSymbol}: Did not post the taker trade order ${orderTxn.id} because the amount after fees was less than or equal to 0`
|
|
2023
1987
|
);
|
|
2024
1988
|
}
|
|
2025
|
-
}
|
|
2026
|
-
|
|
2027
|
-
(
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
if (refundTxn.sourceChainAmount <= 0n) {
|
|
2040
|
-
return;
|
|
2041
|
-
}
|
|
1989
|
+
}
|
|
1990
|
+
|
|
1991
|
+
if (orderTxn.type === 'market') {
|
|
1992
|
+
let refundTxn = {
|
|
1993
|
+
sourceChain: result.taker.sourceChain,
|
|
1994
|
+
sourceWalletAddress: result.taker.sourceWalletAddress,
|
|
1995
|
+
height: orderTxn.height
|
|
1996
|
+
};
|
|
1997
|
+
if (result.taker.sourceChain === this.baseChainSymbol) {
|
|
1998
|
+
refundTxn.sourceChainAmount = result.taker.valueRemaining;
|
|
1999
|
+
} else {
|
|
2000
|
+
refundTxn.sourceChainAmount = result.taker.sizeRemaining;
|
|
2001
|
+
}
|
|
2002
|
+
if (refundTxn.sourceChainAmount > 0n) {
|
|
2042
2003
|
let protocolMessage = this._computeProtocolMessage(refundTxn.sourceChain, 'r4', [orderTxn.id], 'Unmatched market order part');
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2004
|
+
this.scheduleRefundTransaction(
|
|
2005
|
+
refundTxn,
|
|
2006
|
+
latestBlockTimestamp,
|
|
2007
|
+
protocolMessage,
|
|
2008
|
+
{type: 'r4', originOrderId: orderTxn.id},
|
|
2009
|
+
`Chain ${
|
|
2010
|
+
chainSymbol
|
|
2011
|
+
}: Failed to post multisig market order refund transaction of taker ${
|
|
2012
|
+
takerAddress
|
|
2013
|
+
} on chain ${
|
|
2014
|
+
takerTargetChain
|
|
2015
|
+
}`
|
|
2016
|
+
);
|
|
2050
2017
|
}
|
|
2051
|
-
}
|
|
2018
|
+
}
|
|
2052
2019
|
});
|
|
2053
2020
|
|
|
2021
|
+
await this.flushScheduledTransactions();
|
|
2022
|
+
|
|
2054
2023
|
this.processedHeights = {...latestChainHeights};
|
|
2055
2024
|
this.lastProcessedBlocks[blockData.chainSymbol] = blockData;
|
|
2056
2025
|
}
|
|
@@ -2114,34 +2083,33 @@ module.exports = class CapitaliskDEXModule {
|
|
|
2114
2083
|
fromHeight,
|
|
2115
2084
|
toHeight
|
|
2116
2085
|
});
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
);
|
|
2086
|
+
|
|
2087
|
+
for (let dividend of dividendList) {
|
|
2088
|
+
let txnAmount = dividend.amount - BigInt(chainOptions.exchangeFeeBase);
|
|
2089
|
+
if (txnAmount <= 0n) {
|
|
2090
|
+
this.logger.debug(
|
|
2091
|
+
`Chain ${chainSymbol}: Skipped dividend distribution to member address ${
|
|
2092
|
+
dividend.walletAddress
|
|
2093
|
+
} because the amount due after fees was less than or equal to 0`
|
|
2094
|
+
);
|
|
2095
|
+
continue;
|
|
2096
|
+
}
|
|
2097
|
+
let dividendTxn = {
|
|
2098
|
+
recipientAddress: dividend.walletAddress,
|
|
2099
|
+
amount: txnAmount.toString(),
|
|
2100
|
+
fee: chainOptions.exchangeFeeBase.toString(),
|
|
2101
|
+
timestamp: latestBlockTimestamp,
|
|
2102
|
+
height: chainHeight
|
|
2103
|
+
};
|
|
2104
|
+
let protocolMessage = this._computeProtocolMessage(chainSymbol, 'd1', [fromHeight + 1, toHeight], 'Member dividend');
|
|
2105
|
+
this.scheduleMultisigTransaction(
|
|
2106
|
+
chainSymbol,
|
|
2107
|
+
dividendTxn,
|
|
2108
|
+
protocolMessage,
|
|
2109
|
+
null,
|
|
2110
|
+
`Chain ${chainSymbol}: Failed to post multisig dividend transaction to member address ${dividend.walletAddress}`
|
|
2111
|
+
);
|
|
2112
|
+
}
|
|
2145
2113
|
};
|
|
2146
2114
|
|
|
2147
2115
|
let baseChainForkTargetHeight = 0;
|
|
@@ -2632,37 +2600,36 @@ module.exports = class CapitaliskDEXModule {
|
|
|
2632
2600
|
return block;
|
|
2633
2601
|
}
|
|
2634
2602
|
|
|
2635
|
-
|
|
2603
|
+
scheduleRefundOrderBook(snapshot, timestamp, movedToAddresses) {
|
|
2636
2604
|
let allOrders = snapshot.orderBook.bidLimitOrders.concat(snapshot.orderBook.askLimitOrders);
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
);
|
|
2605
|
+
for (let order of allOrders) {
|
|
2606
|
+
let movedToAddress = movedToAddresses[order.sourceChain];
|
|
2607
|
+
let failureMessage = `Failed to post refund transaction for order ${order.id} as part of full order book refund`;
|
|
2608
|
+
if (movedToAddress) {
|
|
2609
|
+
let protocolMessage = this._computeProtocolMessage(order.sourceChain, 'r5', [order.id, movedToAddress], 'DEX has moved');
|
|
2610
|
+
this.scheduleRefundOrder(
|
|
2611
|
+
order,
|
|
2612
|
+
timestamp,
|
|
2613
|
+
snapshot.chainHeights[order.sourceChain],
|
|
2614
|
+
protocolMessage,
|
|
2615
|
+
{type: 'r5', originOrderId: order.id},
|
|
2616
|
+
failureMessage
|
|
2617
|
+
);
|
|
2618
|
+
} else {
|
|
2619
|
+
let protocolMessage = this._computeProtocolMessage(order.sourceChain, 'r6', [order.id], 'DEX has been disabled');
|
|
2620
|
+
this.scheduleRefundOrder(
|
|
2621
|
+
order,
|
|
2622
|
+
timestamp,
|
|
2623
|
+
snapshot.chainHeights[order.sourceChain],
|
|
2624
|
+
protocolMessage,
|
|
2625
|
+
{type: 'r6', originOrderId: order.id},
|
|
2626
|
+
failureMessage
|
|
2627
|
+
);
|
|
2628
|
+
}
|
|
2629
|
+
}
|
|
2663
2630
|
}
|
|
2664
2631
|
|
|
2665
|
-
|
|
2632
|
+
scheduleRefundOrder(order, timestamp, refundHeight, reason, extraTransferData, failureMessage) {
|
|
2666
2633
|
let refundTxn = {
|
|
2667
2634
|
sourceChain: order.sourceChain,
|
|
2668
2635
|
sourceWalletAddress: order.sourceWalletAddress,
|
|
@@ -2673,7 +2640,7 @@ module.exports = class CapitaliskDEXModule {
|
|
|
2673
2640
|
} else {
|
|
2674
2641
|
refundTxn.sourceChainAmount = order.sizeRemaining;
|
|
2675
2642
|
}
|
|
2676
|
-
|
|
2643
|
+
this.scheduleRefundTransaction(refundTxn, timestamp, reason, extraTransferData, failureMessage);
|
|
2677
2644
|
}
|
|
2678
2645
|
|
|
2679
2646
|
_computeProtocolMessage(chainSymbol, code, args, reasonMessage) {
|
|
@@ -2690,15 +2657,16 @@ module.exports = class CapitaliskDEXModule {
|
|
|
2690
2657
|
return messageParts.join(': ');
|
|
2691
2658
|
}
|
|
2692
2659
|
|
|
2693
|
-
|
|
2660
|
+
scheduleRefundTransaction(txn, timestamp, reason, extraTransferData, failureMessage) {
|
|
2694
2661
|
let refundChainOptions = this.options.chains[txn.sourceChain];
|
|
2662
|
+
// Refunds do not charge the exchangeFeeRate.
|
|
2695
2663
|
let refundAmount = txn.sourceChainAmount - BigInt(refundChainOptions.exchangeFeeBase);
|
|
2696
2664
|
|
|
2697
|
-
// Refunds do not charge the exchangeFeeRate.
|
|
2698
2665
|
if (refundAmount <= 0n) {
|
|
2699
|
-
|
|
2700
|
-
|
|
2666
|
+
this.logger.debug(
|
|
2667
|
+
`${failureMessage} because amount was less than or equal to 0`
|
|
2701
2668
|
);
|
|
2669
|
+
return;
|
|
2702
2670
|
}
|
|
2703
2671
|
|
|
2704
2672
|
let refundTxn = {
|
|
@@ -2708,11 +2676,13 @@ module.exports = class CapitaliskDEXModule {
|
|
|
2708
2676
|
timestamp,
|
|
2709
2677
|
height: txn.height
|
|
2710
2678
|
};
|
|
2711
|
-
|
|
2679
|
+
|
|
2680
|
+
this.scheduleMultisigTransaction(
|
|
2712
2681
|
txn.sourceChain,
|
|
2713
2682
|
refundTxn,
|
|
2714
2683
|
reason,
|
|
2715
|
-
extraTransferData
|
|
2684
|
+
extraTransferData,
|
|
2685
|
+
failureMessage
|
|
2716
2686
|
);
|
|
2717
2687
|
}
|
|
2718
2688
|
|
|
@@ -2731,6 +2701,37 @@ module.exports = class CapitaliskDEXModule {
|
|
|
2731
2701
|
}
|
|
2732
2702
|
}
|
|
2733
2703
|
|
|
2704
|
+
scheduleMultisigTransaction(targetChain, transactionData, message, extraTransferData, failureMessage) {
|
|
2705
|
+
this.scheduledTransferInfos.push({
|
|
2706
|
+
targetChain,
|
|
2707
|
+
transactionData,
|
|
2708
|
+
message,
|
|
2709
|
+
extraTransferData,
|
|
2710
|
+
failureMessage
|
|
2711
|
+
});
|
|
2712
|
+
}
|
|
2713
|
+
|
|
2714
|
+
async flushScheduledTransactions() {
|
|
2715
|
+
for (let scheduledTransferInfo of this.scheduledTransferInfos) {
|
|
2716
|
+
let {
|
|
2717
|
+
targetChain,
|
|
2718
|
+
transactionData,
|
|
2719
|
+
message,
|
|
2720
|
+
extraTransferData,
|
|
2721
|
+
failureMessage
|
|
2722
|
+
} = scheduledTransferInfo;
|
|
2723
|
+
|
|
2724
|
+
try {
|
|
2725
|
+
await this.execMultisigTransaction(targetChain, transactionData, message, extraTransferData);
|
|
2726
|
+
} catch (error) {
|
|
2727
|
+
this.logger.debug(
|
|
2728
|
+
`${failureMessage} because of error: ${error.message}`
|
|
2729
|
+
);
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
this.scheduledTransferInfos = [];
|
|
2733
|
+
}
|
|
2734
|
+
|
|
2734
2735
|
async execMultisigTransaction(targetChain, transactionData, message, extraTransferData) {
|
|
2735
2736
|
let chainTimestamp = this._denormalizeTimestamp(targetChain, transactionData.timestamp);
|
|
2736
2737
|
let chainCrypto = this.chainCrypto[targetChain];
|