@hyperlane-xyz/rebalancer 2.0.0 → 3.1.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/dist/bridges/LiFiBridge.d.ts +67 -0
- package/dist/bridges/LiFiBridge.d.ts.map +1 -0
- package/dist/bridges/LiFiBridge.js +386 -0
- package/dist/bridges/LiFiBridge.js.map +1 -0
- package/dist/config/RebalancerConfig.d.ts +8 -2
- package/dist/config/RebalancerConfig.d.ts.map +1 -1
- package/dist/config/RebalancerConfig.js +9 -4
- package/dist/config/RebalancerConfig.js.map +1 -1
- package/dist/config/RebalancerConfig.test.js +135 -1
- package/dist/config/RebalancerConfig.test.js.map +1 -1
- package/dist/config/types.d.ts +1023 -304
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +113 -10
- package/dist/config/types.js.map +1 -1
- package/dist/core/InventoryRebalancer.d.ts +190 -0
- package/dist/core/InventoryRebalancer.d.ts.map +1 -0
- package/dist/core/InventoryRebalancer.js +892 -0
- package/dist/core/InventoryRebalancer.js.map +1 -0
- package/dist/core/InventoryRebalancer.test.d.ts +2 -0
- package/dist/core/InventoryRebalancer.test.d.ts.map +1 -0
- package/dist/core/InventoryRebalancer.test.js +1382 -0
- package/dist/core/InventoryRebalancer.test.js.map +1 -0
- package/dist/core/Rebalancer.d.ts +11 -4
- package/dist/core/Rebalancer.d.ts.map +1 -1
- package/dist/core/Rebalancer.js +92 -9
- package/dist/core/Rebalancer.js.map +1 -1
- package/dist/core/Rebalancer.test.js +82 -49
- package/dist/core/Rebalancer.test.js.map +1 -1
- package/dist/core/RebalancerOrchestrator.d.ts +30 -9
- package/dist/core/RebalancerOrchestrator.d.ts.map +1 -1
- package/dist/core/RebalancerOrchestrator.js +79 -71
- package/dist/core/RebalancerOrchestrator.js.map +1 -1
- package/dist/core/RebalancerOrchestrator.test.d.ts +2 -0
- package/dist/core/RebalancerOrchestrator.test.d.ts.map +1 -0
- package/dist/core/RebalancerOrchestrator.test.js +719 -0
- package/dist/core/RebalancerOrchestrator.test.js.map +1 -0
- package/dist/core/RebalancerService.d.ts +7 -3
- package/dist/core/RebalancerService.d.ts.map +1 -1
- package/dist/core/RebalancerService.js +44 -24
- package/dist/core/RebalancerService.js.map +1 -1
- package/dist/core/RebalancerService.test.js +74 -110
- package/dist/core/RebalancerService.test.js.map +1 -1
- package/dist/e2e/collateral-deficit.e2e-test.js +1 -3
- package/dist/e2e/collateral-deficit.e2e-test.js.map +1 -1
- package/dist/e2e/composite.e2e-test.js.map +1 -1
- package/dist/e2e/harness/BridgeSetup.d.ts +6 -0
- package/dist/e2e/harness/BridgeSetup.d.ts.map +1 -1
- package/dist/e2e/harness/BridgeSetup.js +10 -1
- package/dist/e2e/harness/BridgeSetup.js.map +1 -1
- package/dist/e2e/harness/ForkIndexer.d.ts.map +1 -1
- package/dist/e2e/harness/ForkIndexer.js +1 -0
- package/dist/e2e/harness/ForkIndexer.js.map +1 -1
- package/dist/e2e/harness/TestHelpers.d.ts.map +1 -1
- package/dist/e2e/harness/TestHelpers.js +1 -4
- package/dist/e2e/harness/TestHelpers.js.map +1 -1
- package/dist/e2e/harness/TestRebalancer.d.ts +1 -1
- package/dist/e2e/harness/TestRebalancer.d.ts.map +1 -1
- package/dist/e2e/harness/TestRebalancer.js +9 -9
- package/dist/e2e/harness/TestRebalancer.js.map +1 -1
- package/dist/e2e/minAmount.e2e-test.js +0 -1
- package/dist/e2e/minAmount.e2e-test.js.map +1 -1
- package/dist/e2e/weighted.e2e-test.js +0 -1
- package/dist/e2e/weighted.e2e-test.js.map +1 -1
- package/dist/factories/RebalancerContextFactory.d.ts +48 -6
- package/dist/factories/RebalancerContextFactory.d.ts.map +1 -1
- package/dist/factories/RebalancerContextFactory.js +171 -17
- package/dist/factories/RebalancerContextFactory.js.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/interfaces/IExternalBridge.d.ts +101 -0
- package/dist/interfaces/IExternalBridge.d.ts.map +1 -0
- package/dist/interfaces/IExternalBridge.js +2 -0
- package/dist/interfaces/IExternalBridge.js.map +1 -0
- package/dist/interfaces/IMonitor.d.ts +1 -0
- package/dist/interfaces/IMonitor.d.ts.map +1 -1
- package/dist/interfaces/IRebalancer.d.ts +25 -25
- package/dist/interfaces/IRebalancer.d.ts.map +1 -1
- package/dist/interfaces/IStrategy.d.ts +36 -3
- package/dist/interfaces/IStrategy.d.ts.map +1 -1
- package/dist/interfaces/IStrategy.js +12 -1
- package/dist/interfaces/IStrategy.js.map +1 -1
- package/dist/metrics/PriceGetter.js +1 -1
- package/dist/metrics/PriceGetter.js.map +1 -1
- package/dist/metrics/scripts/metrics.d.ts +3 -3
- package/dist/monitor/Monitor.d.ts +12 -2
- package/dist/monitor/Monitor.d.ts.map +1 -1
- package/dist/monitor/Monitor.js +46 -1
- package/dist/monitor/Monitor.js.map +1 -1
- package/dist/service.js +40 -17
- package/dist/service.js.map +1 -1
- package/dist/strategy/BaseStrategy.d.ts +12 -6
- package/dist/strategy/BaseStrategy.d.ts.map +1 -1
- package/dist/strategy/BaseStrategy.js +56 -21
- package/dist/strategy/BaseStrategy.js.map +1 -1
- package/dist/strategy/CollateralDeficitStrategy.d.ts +1 -1
- package/dist/strategy/CollateralDeficitStrategy.d.ts.map +1 -1
- package/dist/strategy/CollateralDeficitStrategy.js +19 -11
- package/dist/strategy/CollateralDeficitStrategy.js.map +1 -1
- package/dist/strategy/CollateralDeficitStrategy.test.js +135 -2
- package/dist/strategy/CollateralDeficitStrategy.test.js.map +1 -1
- package/dist/strategy/CompositeStrategy.test.js +13 -0
- package/dist/strategy/CompositeStrategy.test.js.map +1 -1
- package/dist/strategy/MinAmountStrategy.test.js +4 -0
- package/dist/strategy/MinAmountStrategy.test.js.map +1 -1
- package/dist/strategy/StrategyFactory.d.ts +2 -1
- package/dist/strategy/StrategyFactory.d.ts.map +1 -1
- package/dist/strategy/StrategyFactory.js +24 -8
- package/dist/strategy/StrategyFactory.js.map +1 -1
- package/dist/strategy/WeightedStrategy.test.js +6 -0
- package/dist/strategy/WeightedStrategy.test.js.map +1 -1
- package/dist/test/helpers.d.ts +8 -7
- package/dist/test/helpers.d.ts.map +1 -1
- package/dist/test/helpers.js +23 -5
- package/dist/test/helpers.js.map +1 -1
- package/dist/test/lifiMocks.d.ts +51 -0
- package/dist/test/lifiMocks.d.ts.map +1 -0
- package/dist/test/lifiMocks.js +130 -0
- package/dist/test/lifiMocks.js.map +1 -0
- package/dist/tracking/ActionTracker.d.ts +34 -1
- package/dist/tracking/ActionTracker.d.ts.map +1 -1
- package/dist/tracking/ActionTracker.js +233 -26
- package/dist/tracking/ActionTracker.js.map +1 -1
- package/dist/tracking/ActionTracker.test.js +380 -19
- package/dist/tracking/ActionTracker.test.js.map +1 -1
- package/dist/tracking/IActionTracker.d.ts +48 -3
- package/dist/tracking/IActionTracker.d.ts.map +1 -1
- package/dist/tracking/InflightContextAdapter.d.ts.map +1 -1
- package/dist/tracking/InflightContextAdapter.js +24 -7
- package/dist/tracking/InflightContextAdapter.js.map +1 -1
- package/dist/tracking/InflightContextAdapter.test.js +7 -4
- package/dist/tracking/InflightContextAdapter.test.js.map +1 -1
- package/dist/tracking/types.d.ts +33 -2
- package/dist/tracking/types.d.ts.map +1 -1
- package/dist/utils/ExplorerClient.d.ts +3 -1
- package/dist/utils/ExplorerClient.d.ts.map +1 -1
- package/dist/utils/ExplorerClient.js +16 -8
- package/dist/utils/ExplorerClient.js.map +1 -1
- package/dist/utils/bridgeUtils.d.ts +27 -4
- package/dist/utils/bridgeUtils.d.ts.map +1 -1
- package/dist/utils/bridgeUtils.js +38 -0
- package/dist/utils/bridgeUtils.js.map +1 -1
- package/dist/utils/bridgeUtils.test.js +9 -0
- package/dist/utils/bridgeUtils.test.js.map +1 -1
- package/dist/utils/gasEstimation.d.ts +65 -0
- package/dist/utils/gasEstimation.d.ts.map +1 -0
- package/dist/utils/gasEstimation.js +176 -0
- package/dist/utils/gasEstimation.js.map +1 -0
- package/dist/utils/tokenUtils.d.ts +9 -1
- package/dist/utils/tokenUtils.d.ts.map +1 -1
- package/dist/utils/tokenUtils.js +11 -0
- package/dist/utils/tokenUtils.js.map +1 -1
- package/package.json +9 -7
- package/src/bridges/LiFiBridge.ts +538 -0
- package/src/config/RebalancerConfig.test.ts +162 -0
- package/src/config/RebalancerConfig.ts +21 -3
- package/src/config/types.ts +147 -10
- package/src/core/InventoryRebalancer.test.ts +1721 -0
- package/src/core/InventoryRebalancer.ts +1265 -0
- package/src/core/Rebalancer.test.ts +84 -30
- package/src/core/Rebalancer.ts +144 -23
- package/src/core/RebalancerOrchestrator.test.ts +869 -0
- package/src/core/RebalancerOrchestrator.ts +146 -95
- package/src/core/RebalancerService.test.ts +86 -124
- package/src/core/RebalancerService.ts +67 -33
- package/src/e2e/collateral-deficit.e2e-test.ts +2 -4
- package/src/e2e/composite.e2e-test.ts +5 -5
- package/src/e2e/harness/BridgeSetup.ts +28 -1
- package/src/e2e/harness/ForkIndexer.ts +1 -0
- package/src/e2e/harness/TestHelpers.ts +1 -4
- package/src/e2e/harness/TestRebalancer.ts +10 -7
- package/src/e2e/minAmount.e2e-test.ts +1 -2
- package/src/e2e/weighted.e2e-test.ts +1 -2
- package/src/factories/RebalancerContextFactory.ts +294 -24
- package/src/index.ts +22 -5
- package/src/interfaces/IExternalBridge.ts +115 -0
- package/src/interfaces/IMonitor.ts +1 -0
- package/src/interfaces/IRebalancer.ts +45 -29
- package/src/interfaces/IStrategy.ts +50 -3
- package/src/metrics/PriceGetter.ts +1 -1
- package/src/monitor/Monitor.ts +81 -2
- package/src/service.ts +59 -18
- package/src/strategy/BaseStrategy.ts +77 -24
- package/src/strategy/CollateralDeficitStrategy.test.ts +181 -4
- package/src/strategy/CollateralDeficitStrategy.ts +42 -15
- package/src/strategy/CompositeStrategy.test.ts +13 -0
- package/src/strategy/MinAmountStrategy.test.ts +4 -0
- package/src/strategy/StrategyFactory.ts +33 -6
- package/src/strategy/WeightedStrategy.test.ts +6 -0
- package/src/test/helpers.ts +39 -14
- package/src/test/lifiMocks.ts +174 -0
- package/src/tracking/ActionTracker.test.ts +443 -19
- package/src/tracking/ActionTracker.ts +339 -28
- package/src/tracking/IActionTracker.ts +59 -3
- package/src/tracking/InflightContextAdapter.test.ts +7 -4
- package/src/tracking/InflightContextAdapter.ts +42 -9
- package/src/tracking/types.ts +45 -2
- package/src/utils/ExplorerClient.ts +27 -10
- package/src/utils/bridgeUtils.test.ts +9 -0
- package/src/utils/bridgeUtils.ts +75 -6
- package/src/utils/gasEstimation.ts +272 -0
- package/src/utils/tokenUtils.ts +12 -0
- package/dist/tracking/index.d.ts +0 -7
- package/dist/tracking/index.d.ts.map +0 -1
- package/dist/tracking/index.js +0 -6
- package/dist/tracking/index.js.map +0 -1
- package/dist/utils/index.d.ts +0 -5
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -5
- package/dist/utils/index.js.map +0 -1
- package/src/tracking/index.ts +0 -36
- package/src/utils/index.ts +0 -4
|
@@ -3,6 +3,7 @@ import chaiAsPromised from 'chai-as-promised';
|
|
|
3
3
|
import { pino } from 'pino';
|
|
4
4
|
import Sinon from 'sinon';
|
|
5
5
|
import { EthJsonRpcBlockParameterTag } from '@hyperlane-xyz/sdk';
|
|
6
|
+
import { DEFAULT_INTENT_TTL_MS } from '../config/types.js';
|
|
6
7
|
import { ActionTracker } from './ActionTracker.js';
|
|
7
8
|
import { InMemoryStore } from './store/InMemoryStore.js';
|
|
8
9
|
chai.use(chaiAsPromised);
|
|
@@ -48,6 +49,7 @@ describe('ActionTracker', () => {
|
|
|
48
49
|
},
|
|
49
50
|
bridges: ['0xbridge1', '0xbridge2'],
|
|
50
51
|
rebalancerAddress: '0xrebalancer',
|
|
52
|
+
intentTTL: DEFAULT_INTENT_TTL_MS,
|
|
51
53
|
};
|
|
52
54
|
tracker = new ActionTracker(transferStore, rebalanceIntentStore, rebalanceActionStore, explorerClient, core, config, testLogger);
|
|
53
55
|
});
|
|
@@ -65,6 +67,7 @@ describe('ActionTracker', () => {
|
|
|
65
67
|
origin_tx_recipient: '0xrouter1',
|
|
66
68
|
is_delivered: false,
|
|
67
69
|
message_body: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064',
|
|
70
|
+
send_occurred_at: null,
|
|
68
71
|
},
|
|
69
72
|
];
|
|
70
73
|
explorerClient.getInflightRebalanceActions.resolves(inflightMessages);
|
|
@@ -87,6 +90,86 @@ describe('ActionTracker', () => {
|
|
|
87
90
|
expect(actions[0].status).to.equal('in_progress');
|
|
88
91
|
expect(actions[0].messageId).to.equal('0xmsg1');
|
|
89
92
|
});
|
|
93
|
+
it('should use send_occurred_at for createdAt when available', async () => {
|
|
94
|
+
const inflightMessages = [
|
|
95
|
+
{
|
|
96
|
+
msg_id: '0xmsg1',
|
|
97
|
+
origin_domain_id: 1,
|
|
98
|
+
destination_domain_id: 2,
|
|
99
|
+
sender: '0xrouter1',
|
|
100
|
+
recipient: '0xrouter2',
|
|
101
|
+
origin_tx_hash: '0xtx1',
|
|
102
|
+
origin_tx_sender: '0xrebalancer',
|
|
103
|
+
origin_tx_recipient: '0xrouter1',
|
|
104
|
+
is_delivered: false,
|
|
105
|
+
message_body: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064',
|
|
106
|
+
send_occurred_at: '2024-01-15T12:30:45',
|
|
107
|
+
},
|
|
108
|
+
];
|
|
109
|
+
explorerClient.getInflightRebalanceActions.resolves(inflightMessages);
|
|
110
|
+
explorerClient.getInflightUserTransfers.resolves([]);
|
|
111
|
+
mailboxStub.isDelivered.resolves(false);
|
|
112
|
+
await tracker.initialize();
|
|
113
|
+
const intents = await rebalanceIntentStore.getAll();
|
|
114
|
+
expect(intents).to.have.lengthOf(1);
|
|
115
|
+
// Hasura timestamps are UTC without 'Z'; recoverAction appends 'Z' before parsing
|
|
116
|
+
const expectedMs = new Date('2024-01-15T12:30:45Z').getTime();
|
|
117
|
+
expect(intents[0].createdAt).to.equal(expectedMs);
|
|
118
|
+
const actions = await rebalanceActionStore.getAll();
|
|
119
|
+
expect(actions[0].createdAt).to.equal(expectedMs);
|
|
120
|
+
});
|
|
121
|
+
it('should fall back to Date.now() when send_occurred_at is null', async () => {
|
|
122
|
+
const before = Date.now();
|
|
123
|
+
const inflightMessages = [
|
|
124
|
+
{
|
|
125
|
+
msg_id: '0xmsg1',
|
|
126
|
+
origin_domain_id: 1,
|
|
127
|
+
destination_domain_id: 2,
|
|
128
|
+
sender: '0xrouter1',
|
|
129
|
+
recipient: '0xrouter2',
|
|
130
|
+
origin_tx_hash: '0xtx1',
|
|
131
|
+
origin_tx_sender: '0xrebalancer',
|
|
132
|
+
origin_tx_recipient: '0xrouter1',
|
|
133
|
+
is_delivered: false,
|
|
134
|
+
message_body: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064',
|
|
135
|
+
send_occurred_at: null,
|
|
136
|
+
},
|
|
137
|
+
];
|
|
138
|
+
explorerClient.getInflightRebalanceActions.resolves(inflightMessages);
|
|
139
|
+
explorerClient.getInflightUserTransfers.resolves([]);
|
|
140
|
+
mailboxStub.isDelivered.resolves(false);
|
|
141
|
+
await tracker.initialize();
|
|
142
|
+
const after = Date.now();
|
|
143
|
+
const intents = await rebalanceIntentStore.getAll();
|
|
144
|
+
expect(intents[0].createdAt).to.be.at.least(before);
|
|
145
|
+
expect(intents[0].createdAt).to.be.at.most(after);
|
|
146
|
+
});
|
|
147
|
+
it('should skip action with invalid send_occurred_at timestamp', async () => {
|
|
148
|
+
const inflightMessages = [
|
|
149
|
+
{
|
|
150
|
+
msg_id: '0xmsg1',
|
|
151
|
+
origin_domain_id: 1,
|
|
152
|
+
destination_domain_id: 2,
|
|
153
|
+
sender: '0xrouter1',
|
|
154
|
+
recipient: '0xrouter2',
|
|
155
|
+
origin_tx_hash: '0xtx1',
|
|
156
|
+
origin_tx_sender: '0xrebalancer',
|
|
157
|
+
origin_tx_recipient: '0xrouter1',
|
|
158
|
+
is_delivered: false,
|
|
159
|
+
message_body: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064',
|
|
160
|
+
send_occurred_at: 'garbage',
|
|
161
|
+
},
|
|
162
|
+
];
|
|
163
|
+
explorerClient.getInflightRebalanceActions.resolves(inflightMessages);
|
|
164
|
+
explorerClient.getInflightUserTransfers.resolves([]);
|
|
165
|
+
mailboxStub.isDelivered.resolves(false);
|
|
166
|
+
await tracker.initialize();
|
|
167
|
+
// Invalid timestamp is caught by recoverAction's catch block, so the action is skipped
|
|
168
|
+
const intents = await rebalanceIntentStore.getAll();
|
|
169
|
+
expect(intents).to.have.lengthOf(0);
|
|
170
|
+
const actions = await rebalanceActionStore.getAll();
|
|
171
|
+
expect(actions).to.have.lengthOf(0);
|
|
172
|
+
});
|
|
90
173
|
it('should skip creating action if it already exists', async () => {
|
|
91
174
|
const inflightMessages = [
|
|
92
175
|
{
|
|
@@ -100,11 +183,13 @@ describe('ActionTracker', () => {
|
|
|
100
183
|
origin_tx_recipient: '0xrouter1',
|
|
101
184
|
is_delivered: false,
|
|
102
185
|
message_body: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064',
|
|
186
|
+
send_occurred_at: null,
|
|
103
187
|
},
|
|
104
188
|
];
|
|
105
189
|
// Pre-create action
|
|
106
190
|
await rebalanceActionStore.save({
|
|
107
191
|
id: '0xmsg1',
|
|
192
|
+
type: 'rebalance_message',
|
|
108
193
|
status: 'in_progress',
|
|
109
194
|
intentId: 'existing-intent',
|
|
110
195
|
messageId: '0xmsg1',
|
|
@@ -139,6 +224,7 @@ describe('ActionTracker', () => {
|
|
|
139
224
|
origin_tx_recipient: '0xrouter1',
|
|
140
225
|
is_delivered: false,
|
|
141
226
|
message_body: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064',
|
|
227
|
+
send_occurred_at: null,
|
|
142
228
|
},
|
|
143
229
|
];
|
|
144
230
|
explorerClient.getInflightUserTransfers.resolves(inflightMessages);
|
|
@@ -176,6 +262,7 @@ describe('ActionTracker', () => {
|
|
|
176
262
|
origin_tx_recipient: '0xrouter1',
|
|
177
263
|
is_delivered: false,
|
|
178
264
|
message_body: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064',
|
|
265
|
+
send_occurred_at: null,
|
|
179
266
|
},
|
|
180
267
|
];
|
|
181
268
|
explorerClient.getInflightUserTransfers.resolves(inflightMessages);
|
|
@@ -206,33 +293,104 @@ describe('ActionTracker', () => {
|
|
|
206
293
|
});
|
|
207
294
|
describe('syncRebalanceIntents', () => {
|
|
208
295
|
it('should mark intents as complete when fully fulfilled', async () => {
|
|
296
|
+
// Intent derives completion from action states, so we need a complete action
|
|
209
297
|
const intent = {
|
|
210
298
|
id: 'intent-1',
|
|
211
299
|
status: 'in_progress',
|
|
212
300
|
origin: 1,
|
|
213
301
|
destination: 2,
|
|
214
302
|
amount: 100n,
|
|
215
|
-
|
|
303
|
+
createdAt: Date.now(),
|
|
304
|
+
updatedAt: Date.now(),
|
|
305
|
+
};
|
|
306
|
+
const action = {
|
|
307
|
+
id: 'action-1',
|
|
308
|
+
type: 'rebalance_message',
|
|
309
|
+
status: 'complete',
|
|
310
|
+
intentId: 'intent-1',
|
|
311
|
+
messageId: '0xmsg1',
|
|
312
|
+
origin: 1,
|
|
313
|
+
destination: 2,
|
|
314
|
+
amount: 100n,
|
|
216
315
|
createdAt: Date.now(),
|
|
217
316
|
updatedAt: Date.now(),
|
|
218
317
|
};
|
|
219
318
|
await rebalanceIntentStore.save(intent);
|
|
319
|
+
await rebalanceActionStore.save(action);
|
|
220
320
|
await tracker.syncRebalanceIntents();
|
|
221
321
|
const updated = await rebalanceIntentStore.get('intent-1');
|
|
222
322
|
expect(updated?.status).to.equal('complete');
|
|
223
323
|
});
|
|
224
324
|
it('should not mark intents as complete if not fully fulfilled', async () => {
|
|
325
|
+
// Intent with only partial completion via actions
|
|
326
|
+
const intent = {
|
|
327
|
+
id: 'intent-1',
|
|
328
|
+
status: 'in_progress',
|
|
329
|
+
origin: 1,
|
|
330
|
+
destination: 2,
|
|
331
|
+
amount: 100n,
|
|
332
|
+
createdAt: Date.now(),
|
|
333
|
+
updatedAt: Date.now(),
|
|
334
|
+
};
|
|
335
|
+
const action = {
|
|
336
|
+
id: 'action-1',
|
|
337
|
+
type: 'rebalance_message',
|
|
338
|
+
status: 'complete',
|
|
339
|
+
intentId: 'intent-1',
|
|
340
|
+
messageId: '0xmsg1',
|
|
341
|
+
origin: 1,
|
|
342
|
+
destination: 2,
|
|
343
|
+
amount: 50n, // Only partial
|
|
344
|
+
createdAt: Date.now(),
|
|
345
|
+
updatedAt: Date.now(),
|
|
346
|
+
};
|
|
347
|
+
await rebalanceIntentStore.save(intent);
|
|
348
|
+
await rebalanceActionStore.save(action);
|
|
349
|
+
await tracker.syncRebalanceIntents();
|
|
350
|
+
const updated = await rebalanceIntentStore.get('intent-1');
|
|
351
|
+
expect(updated?.status).to.equal('in_progress');
|
|
352
|
+
});
|
|
353
|
+
it('should mark unfulfilled intents as failed when TTL exceeded', async () => {
|
|
225
354
|
const intent = {
|
|
226
355
|
id: 'intent-1',
|
|
227
356
|
status: 'in_progress',
|
|
228
357
|
origin: 1,
|
|
229
358
|
destination: 2,
|
|
230
359
|
amount: 100n,
|
|
231
|
-
|
|
360
|
+
createdAt: Date.now() - DEFAULT_INTENT_TTL_MS - 1,
|
|
361
|
+
updatedAt: Date.now(),
|
|
362
|
+
};
|
|
363
|
+
const action = {
|
|
364
|
+
id: 'action-1',
|
|
365
|
+
type: 'rebalance_message',
|
|
366
|
+
status: 'in_progress',
|
|
367
|
+
intentId: 'intent-1',
|
|
368
|
+
messageId: '0xmsg1',
|
|
369
|
+
origin: 1,
|
|
370
|
+
destination: 2,
|
|
371
|
+
amount: 50n,
|
|
232
372
|
createdAt: Date.now(),
|
|
233
373
|
updatedAt: Date.now(),
|
|
234
374
|
};
|
|
235
375
|
await rebalanceIntentStore.save(intent);
|
|
376
|
+
await rebalanceActionStore.save(action);
|
|
377
|
+
await tracker.syncRebalanceIntents();
|
|
378
|
+
const updatedIntent = await rebalanceIntentStore.get('intent-1');
|
|
379
|
+
expect(updatedIntent?.status).to.equal('failed');
|
|
380
|
+
const updatedAction = await rebalanceActionStore.get('action-1');
|
|
381
|
+
expect(updatedAction?.status).to.equal('failed');
|
|
382
|
+
});
|
|
383
|
+
it('should not expire intents within TTL', async () => {
|
|
384
|
+
const intent = {
|
|
385
|
+
id: 'intent-1',
|
|
386
|
+
status: 'in_progress',
|
|
387
|
+
origin: 1,
|
|
388
|
+
destination: 2,
|
|
389
|
+
amount: 100n,
|
|
390
|
+
createdAt: Date.now() - DEFAULT_INTENT_TTL_MS + 60_000,
|
|
391
|
+
updatedAt: Date.now(),
|
|
392
|
+
};
|
|
393
|
+
await rebalanceIntentStore.save(intent);
|
|
236
394
|
await tracker.syncRebalanceIntents();
|
|
237
395
|
const updated = await rebalanceIntentStore.get('intent-1');
|
|
238
396
|
expect(updated?.status).to.equal('in_progress');
|
|
@@ -246,12 +404,12 @@ describe('ActionTracker', () => {
|
|
|
246
404
|
origin: 1,
|
|
247
405
|
destination: 2,
|
|
248
406
|
amount: 100n,
|
|
249
|
-
fulfilledAmount: 0n,
|
|
250
407
|
createdAt: Date.now(),
|
|
251
408
|
updatedAt: Date.now(),
|
|
252
409
|
};
|
|
253
410
|
const action = {
|
|
254
411
|
id: 'action-1',
|
|
412
|
+
type: 'rebalance_message',
|
|
255
413
|
status: 'in_progress',
|
|
256
414
|
intentId: 'intent-1',
|
|
257
415
|
messageId: '0xmsg1',
|
|
@@ -268,14 +426,14 @@ describe('ActionTracker', () => {
|
|
|
268
426
|
// Action should be complete
|
|
269
427
|
const updatedAction = await rebalanceActionStore.get('action-1');
|
|
270
428
|
expect(updatedAction?.status).to.equal('complete');
|
|
271
|
-
// Intent should be
|
|
429
|
+
// Intent should be complete (derived from completed action amounts)
|
|
272
430
|
const updatedIntent = await rebalanceIntentStore.get('intent-1');
|
|
273
|
-
expect(updatedIntent?.fulfilledAmount).to.equal(100n);
|
|
274
431
|
expect(updatedIntent?.status).to.equal('complete');
|
|
275
432
|
});
|
|
276
433
|
it('should not mark actions as complete if not delivered', async () => {
|
|
277
434
|
const action = {
|
|
278
435
|
id: 'action-1',
|
|
436
|
+
type: 'rebalance_message',
|
|
279
437
|
status: 'in_progress',
|
|
280
438
|
intentId: 'intent-1',
|
|
281
439
|
messageId: '0xmsg1',
|
|
@@ -331,7 +489,6 @@ describe('ActionTracker', () => {
|
|
|
331
489
|
origin: 1,
|
|
332
490
|
destination: 2,
|
|
333
491
|
amount: 100n,
|
|
334
|
-
fulfilledAmount: 0n,
|
|
335
492
|
createdAt: Date.now(),
|
|
336
493
|
updatedAt: Date.now(),
|
|
337
494
|
});
|
|
@@ -341,7 +498,6 @@ describe('ActionTracker', () => {
|
|
|
341
498
|
origin: 2,
|
|
342
499
|
destination: 3,
|
|
343
500
|
amount: 200n,
|
|
344
|
-
fulfilledAmount: 50n,
|
|
345
501
|
createdAt: Date.now(),
|
|
346
502
|
updatedAt: Date.now(),
|
|
347
503
|
});
|
|
@@ -351,7 +507,6 @@ describe('ActionTracker', () => {
|
|
|
351
507
|
origin: 3,
|
|
352
508
|
destination: 1,
|
|
353
509
|
amount: 300n,
|
|
354
|
-
fulfilledAmount: 300n,
|
|
355
510
|
createdAt: Date.now(),
|
|
356
511
|
updatedAt: Date.now(),
|
|
357
512
|
});
|
|
@@ -362,6 +517,214 @@ describe('ActionTracker', () => {
|
|
|
362
517
|
expect(result[0].id).to.equal('intent-2');
|
|
363
518
|
});
|
|
364
519
|
});
|
|
520
|
+
describe('getPartiallyFulfilledInventoryIntents', () => {
|
|
521
|
+
it('returns not_started inventory intents', async () => {
|
|
522
|
+
// Create a not_started inventory intent (simulates failed execution before any action created)
|
|
523
|
+
await rebalanceIntentStore.save({
|
|
524
|
+
id: 'stuck-intent',
|
|
525
|
+
status: 'not_started',
|
|
526
|
+
origin: 1,
|
|
527
|
+
destination: 2,
|
|
528
|
+
amount: 1000000000000000000n, // 1 ETH
|
|
529
|
+
executionMethod: 'inventory',
|
|
530
|
+
createdAt: Date.now(),
|
|
531
|
+
updatedAt: Date.now(),
|
|
532
|
+
});
|
|
533
|
+
// Should be returned even though status is 'not_started'
|
|
534
|
+
const partialIntents = await tracker.getPartiallyFulfilledInventoryIntents();
|
|
535
|
+
expect(partialIntents).to.have.lengthOf(1);
|
|
536
|
+
expect(partialIntents[0].intent.id).to.equal('stuck-intent');
|
|
537
|
+
expect(partialIntents[0].completedAmount).to.equal(0n);
|
|
538
|
+
expect(partialIntents[0].remaining).to.equal(1000000000000000000n);
|
|
539
|
+
});
|
|
540
|
+
it('returns in_progress inventory intents with partial completion', async () => {
|
|
541
|
+
// Create an in_progress inventory intent with a completed action
|
|
542
|
+
await rebalanceIntentStore.save({
|
|
543
|
+
id: 'partial-intent',
|
|
544
|
+
status: 'in_progress',
|
|
545
|
+
origin: 1,
|
|
546
|
+
destination: 2,
|
|
547
|
+
amount: 1000000000000000000n, // 1 ETH
|
|
548
|
+
executionMethod: 'inventory',
|
|
549
|
+
createdAt: Date.now(),
|
|
550
|
+
updatedAt: Date.now(),
|
|
551
|
+
});
|
|
552
|
+
// Create a completed inventory_deposit action for partial amount
|
|
553
|
+
await rebalanceActionStore.save({
|
|
554
|
+
id: 'action-1',
|
|
555
|
+
type: 'inventory_deposit',
|
|
556
|
+
status: 'complete',
|
|
557
|
+
intentId: 'partial-intent',
|
|
558
|
+
origin: 1,
|
|
559
|
+
destination: 2,
|
|
560
|
+
amount: 400000000000000000n, // 0.4 ETH completed
|
|
561
|
+
createdAt: Date.now(),
|
|
562
|
+
updatedAt: Date.now(),
|
|
563
|
+
});
|
|
564
|
+
const partialIntents = await tracker.getPartiallyFulfilledInventoryIntents();
|
|
565
|
+
expect(partialIntents).to.have.lengthOf(1);
|
|
566
|
+
expect(partialIntents[0].intent.id).to.equal('partial-intent');
|
|
567
|
+
expect(partialIntents[0].completedAmount).to.equal(400000000000000000n);
|
|
568
|
+
expect(partialIntents[0].remaining).to.equal(600000000000000000n); // 0.6 ETH remaining
|
|
569
|
+
});
|
|
570
|
+
it('does not return non-inventory intents', async () => {
|
|
571
|
+
// Create a not_started intent without executionMethod: 'inventory'
|
|
572
|
+
await rebalanceIntentStore.save({
|
|
573
|
+
id: 'non-inventory-intent',
|
|
574
|
+
status: 'not_started',
|
|
575
|
+
origin: 1,
|
|
576
|
+
destination: 2,
|
|
577
|
+
amount: 1000000000000000000n,
|
|
578
|
+
// executionMethod is undefined - not an inventory intent
|
|
579
|
+
createdAt: Date.now(),
|
|
580
|
+
updatedAt: Date.now(),
|
|
581
|
+
});
|
|
582
|
+
const partialIntents = await tracker.getPartiallyFulfilledInventoryIntents();
|
|
583
|
+
expect(partialIntents).to.have.lengthOf(0);
|
|
584
|
+
});
|
|
585
|
+
it('returns intent with in-flight deposit and sets hasInflightDeposit flag', async () => {
|
|
586
|
+
// Setup: in_progress inventory intent (amount: 1 ETH = 1_000_000_000_000_000_000n)
|
|
587
|
+
await rebalanceIntentStore.save({
|
|
588
|
+
id: 'intent-with-inflight',
|
|
589
|
+
status: 'in_progress',
|
|
590
|
+
origin: 1,
|
|
591
|
+
destination: 2,
|
|
592
|
+
amount: 1000000000000000000n, // 1 ETH
|
|
593
|
+
executionMethod: 'inventory',
|
|
594
|
+
createdAt: Date.now(),
|
|
595
|
+
updatedAt: Date.now(),
|
|
596
|
+
});
|
|
597
|
+
// Complete inventory_deposit action (amount: 400_000_000_000_000_000n = 0.4 ETH)
|
|
598
|
+
await rebalanceActionStore.save({
|
|
599
|
+
id: 'action-complete',
|
|
600
|
+
type: 'inventory_deposit',
|
|
601
|
+
status: 'complete',
|
|
602
|
+
intentId: 'intent-with-inflight',
|
|
603
|
+
origin: 1,
|
|
604
|
+
destination: 2,
|
|
605
|
+
amount: 400000000000000000n, // 0.4 ETH completed
|
|
606
|
+
createdAt: Date.now(),
|
|
607
|
+
updatedAt: Date.now(),
|
|
608
|
+
});
|
|
609
|
+
// In_progress inventory_deposit action (amount: 300_000_000_000_000_000n = 0.3 ETH)
|
|
610
|
+
await rebalanceActionStore.save({
|
|
611
|
+
id: 'action-inflight',
|
|
612
|
+
type: 'inventory_deposit',
|
|
613
|
+
status: 'in_progress',
|
|
614
|
+
intentId: 'intent-with-inflight',
|
|
615
|
+
origin: 1,
|
|
616
|
+
destination: 2,
|
|
617
|
+
amount: 300000000000000000n, // 0.3 ETH in-flight
|
|
618
|
+
createdAt: Date.now(),
|
|
619
|
+
updatedAt: Date.now(),
|
|
620
|
+
});
|
|
621
|
+
const partialIntents = await tracker.getPartiallyFulfilledInventoryIntents();
|
|
622
|
+
expect(partialIntents).to.have.lengthOf(1);
|
|
623
|
+
expect(partialIntents[0].hasInflightDeposit).to.be.true;
|
|
624
|
+
expect(partialIntents[0].completedAmount).to.equal(400000000000000000n);
|
|
625
|
+
expect(partialIntents[0].remaining).to.equal(300000000000000000n); // 1.0 - 0.4 - 0.3
|
|
626
|
+
});
|
|
627
|
+
it('returns intent without in-flight deposit with hasInflightDeposit false', async () => {
|
|
628
|
+
// Setup: in_progress inventory intent (amount: 1 ETH)
|
|
629
|
+
await rebalanceIntentStore.save({
|
|
630
|
+
id: 'intent-no-inflight',
|
|
631
|
+
status: 'in_progress',
|
|
632
|
+
origin: 1,
|
|
633
|
+
destination: 2,
|
|
634
|
+
amount: 1000000000000000000n, // 1 ETH
|
|
635
|
+
executionMethod: 'inventory',
|
|
636
|
+
createdAt: Date.now(),
|
|
637
|
+
updatedAt: Date.now(),
|
|
638
|
+
});
|
|
639
|
+
// Complete inventory_deposit action (amount: 0.4 ETH)
|
|
640
|
+
await rebalanceActionStore.save({
|
|
641
|
+
id: 'action-complete-only',
|
|
642
|
+
type: 'inventory_deposit',
|
|
643
|
+
status: 'complete',
|
|
644
|
+
intentId: 'intent-no-inflight',
|
|
645
|
+
origin: 1,
|
|
646
|
+
destination: 2,
|
|
647
|
+
amount: 400000000000000000n, // 0.4 ETH completed
|
|
648
|
+
createdAt: Date.now(),
|
|
649
|
+
updatedAt: Date.now(),
|
|
650
|
+
});
|
|
651
|
+
// NO in_progress inventory_deposit actions
|
|
652
|
+
const partialIntents = await tracker.getPartiallyFulfilledInventoryIntents();
|
|
653
|
+
expect(partialIntents).to.have.lengthOf(1);
|
|
654
|
+
expect(partialIntents[0].hasInflightDeposit).to.be.false;
|
|
655
|
+
expect(partialIntents[0].remaining).to.equal(600000000000000000n);
|
|
656
|
+
});
|
|
657
|
+
it('returns intent when remaining is 0n but has in-flight deposit', async () => {
|
|
658
|
+
// intent.amount = 1 ETH, completedAmount = 0.7 ETH, inflightAmount = 0.3 ETH → remaining = 0n
|
|
659
|
+
await rebalanceIntentStore.save({
|
|
660
|
+
id: 'intent-zero-remaining',
|
|
661
|
+
status: 'in_progress',
|
|
662
|
+
origin: 1,
|
|
663
|
+
destination: 2,
|
|
664
|
+
amount: 1000000000000000000n, // 1 ETH
|
|
665
|
+
executionMethod: 'inventory',
|
|
666
|
+
createdAt: Date.now(),
|
|
667
|
+
updatedAt: Date.now(),
|
|
668
|
+
});
|
|
669
|
+
// 0.7 ETH already completed
|
|
670
|
+
await rebalanceActionStore.save({
|
|
671
|
+
id: 'action-complete-part',
|
|
672
|
+
type: 'inventory_deposit',
|
|
673
|
+
status: 'complete',
|
|
674
|
+
intentId: 'intent-zero-remaining',
|
|
675
|
+
origin: 1,
|
|
676
|
+
destination: 2,
|
|
677
|
+
amount: 700000000000000000n, // 0.7 ETH
|
|
678
|
+
createdAt: Date.now(),
|
|
679
|
+
updatedAt: Date.now(),
|
|
680
|
+
});
|
|
681
|
+
// 0.3 ETH in-flight — exactly fills the remaining gap
|
|
682
|
+
await rebalanceActionStore.save({
|
|
683
|
+
id: 'action-inflight-rest',
|
|
684
|
+
type: 'inventory_deposit',
|
|
685
|
+
status: 'in_progress',
|
|
686
|
+
intentId: 'intent-zero-remaining',
|
|
687
|
+
origin: 1,
|
|
688
|
+
destination: 2,
|
|
689
|
+
amount: 300000000000000000n, // 0.3 ETH in-flight
|
|
690
|
+
createdAt: Date.now(),
|
|
691
|
+
updatedAt: Date.now(),
|
|
692
|
+
});
|
|
693
|
+
const partialIntents = await tracker.getPartiallyFulfilledInventoryIntents();
|
|
694
|
+
expect(partialIntents).to.have.lengthOf(1);
|
|
695
|
+
expect(partialIntents[0].remaining).to.equal(0n);
|
|
696
|
+
expect(partialIntents[0].hasInflightDeposit).to.be.true;
|
|
697
|
+
expect(partialIntents[0].completedAmount).to.equal(700000000000000000n);
|
|
698
|
+
});
|
|
699
|
+
it('does not return fully completed intent with no in-flight deposits', async () => {
|
|
700
|
+
// intent.amount = 1 ETH, completedAmount = 1 ETH, inflightAmount = 0 → remaining = 0n, no inflight
|
|
701
|
+
await rebalanceIntentStore.save({
|
|
702
|
+
id: 'intent-fully-done',
|
|
703
|
+
status: 'in_progress',
|
|
704
|
+
origin: 1,
|
|
705
|
+
destination: 2,
|
|
706
|
+
amount: 1000000000000000000n, // 1 ETH
|
|
707
|
+
executionMethod: 'inventory',
|
|
708
|
+
createdAt: Date.now(),
|
|
709
|
+
updatedAt: Date.now(),
|
|
710
|
+
});
|
|
711
|
+
// Full amount completed
|
|
712
|
+
await rebalanceActionStore.save({
|
|
713
|
+
id: 'action-all-done',
|
|
714
|
+
type: 'inventory_deposit',
|
|
715
|
+
status: 'complete',
|
|
716
|
+
intentId: 'intent-fully-done',
|
|
717
|
+
origin: 1,
|
|
718
|
+
destination: 2,
|
|
719
|
+
amount: 1000000000000000000n, // 1 ETH — full amount
|
|
720
|
+
createdAt: Date.now(),
|
|
721
|
+
updatedAt: Date.now(),
|
|
722
|
+
});
|
|
723
|
+
const partialIntents = await tracker.getPartiallyFulfilledInventoryIntents();
|
|
724
|
+
// remaining = 0n AND inflightAmount = 0n → should NOT be returned
|
|
725
|
+
expect(partialIntents).to.have.lengthOf(0);
|
|
726
|
+
});
|
|
727
|
+
});
|
|
365
728
|
describe('createRebalanceIntent', () => {
|
|
366
729
|
it('should create a new intent with status not_started', async () => {
|
|
367
730
|
const result = await tracker.createRebalanceIntent({
|
|
@@ -375,7 +738,6 @@ describe('ActionTracker', () => {
|
|
|
375
738
|
expect(result.origin).to.equal(1);
|
|
376
739
|
expect(result.destination).to.equal(2);
|
|
377
740
|
expect(result.amount).to.equal(100n);
|
|
378
|
-
expect(result.fulfilledAmount).to.equal(0n);
|
|
379
741
|
expect(result.priority).to.equal(1);
|
|
380
742
|
expect(result.strategyType).to.equal('MinAmountStrategy');
|
|
381
743
|
const stored = await rebalanceIntentStore.get(result.id);
|
|
@@ -390,12 +752,12 @@ describe('ActionTracker', () => {
|
|
|
390
752
|
origin: 1,
|
|
391
753
|
destination: 2,
|
|
392
754
|
amount: 100n,
|
|
393
|
-
fulfilledAmount: 0n,
|
|
394
755
|
createdAt: Date.now(),
|
|
395
756
|
updatedAt: Date.now(),
|
|
396
757
|
};
|
|
397
758
|
await rebalanceIntentStore.save(intent);
|
|
398
759
|
const result = await tracker.createRebalanceAction({
|
|
760
|
+
type: 'rebalance_message',
|
|
399
761
|
intentId: 'intent-1',
|
|
400
762
|
origin: 1,
|
|
401
763
|
destination: 2,
|
|
@@ -416,12 +778,12 @@ describe('ActionTracker', () => {
|
|
|
416
778
|
origin: 1,
|
|
417
779
|
destination: 2,
|
|
418
780
|
amount: 100n,
|
|
419
|
-
fulfilledAmount: 50n,
|
|
420
781
|
createdAt: Date.now(),
|
|
421
782
|
updatedAt: Date.now(),
|
|
422
783
|
};
|
|
423
784
|
await rebalanceIntentStore.save(intent);
|
|
424
785
|
await tracker.createRebalanceAction({
|
|
786
|
+
type: 'rebalance_message',
|
|
425
787
|
intentId: 'intent-1',
|
|
426
788
|
origin: 1,
|
|
427
789
|
destination: 2,
|
|
@@ -431,23 +793,22 @@ describe('ActionTracker', () => {
|
|
|
431
793
|
});
|
|
432
794
|
const updatedIntent = await rebalanceIntentStore.get('intent-1');
|
|
433
795
|
expect(updatedIntent?.status).to.equal('in_progress');
|
|
434
|
-
expect(updatedIntent?.fulfilledAmount).to.equal(50n); // Should not change
|
|
435
796
|
});
|
|
436
797
|
});
|
|
437
798
|
describe('completeRebalanceAction', () => {
|
|
438
|
-
it('should mark action as complete and
|
|
799
|
+
it('should mark action as complete and mark parent intent complete if fully fulfilled', async () => {
|
|
439
800
|
const intent = {
|
|
440
801
|
id: 'intent-1',
|
|
441
802
|
status: 'in_progress',
|
|
442
803
|
origin: 1,
|
|
443
804
|
destination: 2,
|
|
444
805
|
amount: 100n,
|
|
445
|
-
fulfilledAmount: 0n,
|
|
446
806
|
createdAt: Date.now(),
|
|
447
807
|
updatedAt: Date.now(),
|
|
448
808
|
};
|
|
449
809
|
const action = {
|
|
450
810
|
id: 'action-1',
|
|
811
|
+
type: 'rebalance_message',
|
|
451
812
|
status: 'in_progress',
|
|
452
813
|
intentId: 'intent-1',
|
|
453
814
|
messageId: '0xmsg1',
|
|
@@ -462,8 +823,8 @@ describe('ActionTracker', () => {
|
|
|
462
823
|
await tracker.completeRebalanceAction('action-1');
|
|
463
824
|
const updatedAction = await rebalanceActionStore.get('action-1');
|
|
464
825
|
expect(updatedAction?.status).to.equal('complete');
|
|
826
|
+
// Intent should be complete (derived from completed action amounts)
|
|
465
827
|
const updatedIntent = await rebalanceIntentStore.get('intent-1');
|
|
466
|
-
expect(updatedIntent?.fulfilledAmount).to.equal(100n);
|
|
467
828
|
expect(updatedIntent?.status).to.equal('complete');
|
|
468
829
|
});
|
|
469
830
|
it('should throw error when action not found', async () => {
|
|
@@ -478,7 +839,6 @@ describe('ActionTracker', () => {
|
|
|
478
839
|
origin: 1,
|
|
479
840
|
destination: 2,
|
|
480
841
|
amount: 100n,
|
|
481
|
-
fulfilledAmount: 0n,
|
|
482
842
|
createdAt: Date.now(),
|
|
483
843
|
updatedAt: Date.now(),
|
|
484
844
|
};
|
|
@@ -492,6 +852,7 @@ describe('ActionTracker', () => {
|
|
|
492
852
|
it('should mark action as failed', async () => {
|
|
493
853
|
const action = {
|
|
494
854
|
id: 'action-1',
|
|
855
|
+
type: 'rebalance_message',
|
|
495
856
|
status: 'in_progress',
|
|
496
857
|
intentId: 'intent-1',
|
|
497
858
|
messageId: '0xmsg1',
|
|
@@ -527,7 +888,7 @@ describe('ActionTracker', () => {
|
|
|
527
888
|
expect(call).to.not.be.null;
|
|
528
889
|
const params = call.args[0];
|
|
529
890
|
expect(params.routersByDomain).to.deep.equal(config.routersByDomain);
|
|
530
|
-
expect(params.
|
|
891
|
+
expect(params.excludeTxSenders).to.deep.equal([config.rebalancerAddress]);
|
|
531
892
|
});
|
|
532
893
|
});
|
|
533
894
|
describe('delivery check synchronization', () => {
|
|
@@ -560,12 +921,12 @@ describe('ActionTracker', () => {
|
|
|
560
921
|
origin: 1,
|
|
561
922
|
destination: 2,
|
|
562
923
|
amount: 100n,
|
|
563
|
-
fulfilledAmount: 0n,
|
|
564
924
|
createdAt: Date.now(),
|
|
565
925
|
updatedAt: Date.now(),
|
|
566
926
|
};
|
|
567
927
|
const action = {
|
|
568
928
|
id: 'action-1',
|
|
929
|
+
type: 'rebalance_message',
|
|
569
930
|
status: 'in_progress',
|
|
570
931
|
intentId: 'intent-1',
|
|
571
932
|
messageId: '0xmsg1',
|
|
@@ -655,13 +1016,13 @@ describe('ActionTracker', () => {
|
|
|
655
1016
|
origin: 1,
|
|
656
1017
|
destination: 2,
|
|
657
1018
|
amount: 100n,
|
|
658
|
-
fulfilledAmount: 0n,
|
|
659
1019
|
createdAt: Date.now(),
|
|
660
1020
|
updatedAt: Date.now(),
|
|
661
1021
|
};
|
|
662
1022
|
const action = {
|
|
663
1023
|
id: 'action-1',
|
|
664
1024
|
status: 'in_progress',
|
|
1025
|
+
type: 'rebalance_message',
|
|
665
1026
|
intentId: 'intent-1',
|
|
666
1027
|
messageId: '0xmsg1',
|
|
667
1028
|
origin: 1,
|