Skip to content

Commit 9c74668

Browse files
committed
fix(wallet): tx not withdrawing all rewards
WHAT: This commit updates the pending requests observable to emit any pending requests updates immediately, while debouncing only non-pending updates. WHY: simple-delegation-rewards e2e test started failing due to transaction not withdrawing all rewards. Issue was exposed after the websocket networkInfo provider was implemented and activated for the e2e tests, making responses instant (as opposed to slower HTTP requests). Wallet syncStatus updates were debounced causing the syncStatus not to update in case of many bursting requests, effectively causing the TxBuilder to consider the providers synced.
1 parent 8251245 commit 9c74668

File tree

3 files changed

+52
-12
lines changed

3 files changed

+52
-12
lines changed

packages/e2e/src/util/util.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ export const normalizeTxBody = (body: Cardano.HydratedTxBody | Cardano.TxBody) =
8383
dehydratedTx.inputs = sortTxIn(dehydratedTx.inputs);
8484
dehydratedTx.collaterals = sortTxIn(dehydratedTx.collaterals);
8585
dehydratedTx.referenceInputs = sortTxIn(dehydratedTx.referenceInputs);
86+
if (dehydratedTx.withdrawals) {
87+
dehydratedTx.withdrawals = sortBy(dehydratedTx.withdrawals, ['stakeAddress']);
88+
}
8689

8790
return dehydratedTx;
8891
};

packages/wallet/src/services/ProviderTracker/ProviderStatusTracker.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ import {
33
Observable,
44
combineLatest,
55
concat,
6+
debounce,
67
debounceTime,
78
distinctUntilChanged,
89
filter,
10+
interval,
911
map,
1012
mergeMap,
1113
of,
@@ -79,13 +81,15 @@ export const createProviderStatusTracker = (
7981
const relevantStats$ = getProviderSyncRelevantStats(dependencies).pipe(share());
8082
const isAnyRequestPending$ = new TrackerSubject<boolean>(
8183
relevantStats$.pipe(
82-
debounceTime(1), // resolved requests could trigger new requests
8384
map((allStats) =>
8485
allStats.some(
8586
({ numCalls, numFailures, numResponses, didLastRequestFail }) =>
8687
didLastRequestFail || numCalls > numResponses + numFailures
8788
)
8889
),
90+
// do not debounce if there are pending requests; in case of many requests, it will be debounced
91+
// for a long time, leaving the previous status unchanged
92+
debounce((isReqPending) => (isReqPending ? of(true) : interval(1))),
8993
distinctUntilChanged(),
9094
tap((isReqPending) => logger.debug(`${isReqPending ? 'Some' : 'No'} requests are pending`))
9195
)

packages/wallet/test/services/ProviderTracker/ProviderStatusTracker.test.ts

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,15 @@ describe('createProviderStatusTracker', () => {
8080
rewardsProvider = new TrackedRewardsProvider(mockRewardsProvider());
8181
});
8282

83+
// n - not pending
84+
// p - pending
8385
it('isAnyRequestPending$: true if there are any reqs in flight, false when all resolved', () => {
8486
createTestScheduler().run(({ cold, expectObservable }) => {
87+
const source = 'ab-c-d-e-f-g-h-i';
88+
const status = '-p--np--np------n';
8589
const getProviderSyncRelevantStats = jest
8690
.fn()
87-
.mockReturnValueOnce(cold<ProviderFnStats[]>('ab-c-d-e-f-g-h-i', providerFnStats));
91+
.mockReturnValueOnce(cold<ProviderFnStats[]>(source, providerFnStats));
8892
const tracker = createProviderStatusTracker(
8993
{
9094
assetProvider,
@@ -99,23 +103,52 @@ describe('createProviderStatusTracker', () => {
99103
{ getProviderSyncRelevantStats }
100104
);
101105
// debounced by 1
102-
expectObservable(tracker.isAnyRequestPending$).toBe('--b-c-d-e-f-----i', {
103-
b: true,
104-
c: false,
105-
d: true,
106-
e: false,
107-
f: true,
108-
i: false
106+
expectObservable(tracker.isAnyRequestPending$).toBe(status, {
107+
n: false,
108+
p: true
109109
});
110110
});
111111
});
112112

113-
// eslint-disable-next-line max-len
113+
it.each([
114+
{ descr: 'not-pending is debounced', expected: '---n|', source: 'aaa-|' },
115+
{ descr: 'pending are not debounced', expected: 'p--|', source: 'bbb|' },
116+
{ descr: 'not-pending are dropped because they were debounced, pending is emitted immediately', expected: '--p|', source: 'aab|' },
117+
{ descr: 'flipping pending status shows pending, then waits for the first not-pending debounce to expire', expected: 'p-----n|', source: 'bababa-|' }
118+
])('isAnyRequestPending$: %s', ({ descr, source, expected }) => {
119+
createTestScheduler().run(({ cold, expectObservable }) => {
120+
const getProviderSyncRelevantStats = jest
121+
.fn()
122+
.mockReturnValueOnce(cold<ProviderFnStats[]>(source, providerFnStats));
123+
124+
const tracker = createProviderStatusTracker(
125+
{
126+
assetProvider,
127+
chainHistoryProvider,
128+
logger: dummyLogger,
129+
networkInfoProvider,
130+
rewardsProvider,
131+
stakePoolProvider,
132+
utxoProvider
133+
},
134+
{ consideredOutOfSyncAfter: timeout },
135+
{ getProviderSyncRelevantStats }
136+
);
137+
138+
expectObservable(tracker.isAnyRequestPending$).toBe(expected, {
139+
n: false,
140+
p: true
141+
}, descr);
142+
});
143+
});
144+
114145
it('isSettled$: false on load, true when all requests are resolved, then reverse of isAnyRequestPending', async () => {
115146
createTestScheduler().run(({ cold, expectObservable }) => {
147+
const source = '-a-b-c-d-e-f-g-h-i';
148+
const settle = 'a---------ef------i';
116149
const getProviderSyncRelevantStats = jest
117150
.fn()
118-
.mockReturnValueOnce(cold<ProviderFnStats[]>('-a-b-c-d-e-f-g-h-i', providerFnStats));
151+
.mockReturnValueOnce(cold<ProviderFnStats[]>(source, providerFnStats));
119152
const tracker = createProviderStatusTracker(
120153
{
121154
assetProvider,
@@ -130,7 +163,7 @@ describe('createProviderStatusTracker', () => {
130163
{ getProviderSyncRelevantStats }
131164
);
132165
// debounced by 1
133-
expectObservable(tracker.isSettled$).toBe('a---------e-f-----i', {
166+
expectObservable(tracker.isSettled$).toBe(settle, {
134167
a: false,
135168
e: true,
136169
f: false,

0 commit comments

Comments
 (0)