Skip to content

Commit d59b04c

Browse files
committed
sdk: adapt transfers epics
1 parent 66eb34f commit d59b04c

File tree

10 files changed

+610
-858
lines changed

10 files changed

+610
-858
lines changed

raiden-ts/src/transfers/epics/close.ts

Lines changed: 0 additions & 69 deletions
This file was deleted.
Lines changed: 40 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,19 @@
11
import { from, merge, Observable, of } from 'rxjs';
2-
import { exhaustMap, filter, withLatestFrom, mergeMap } from 'rxjs/operators';
2+
import { exhaustMap, filter, mergeMap, pluck, withLatestFrom } from 'rxjs/operators';
33

44
import { RaidenAction } from '../../actions';
55
import { newBlock } from '../../channels/actions';
6-
import { RaidenConfig } from '../../config';
76
import { RaidenState } from '../../state';
87
import { RaidenEpicDeps } from '../../types';
9-
import { isActionOf, isResponseOf } from '../../utils/actions';
8+
import { isResponseOf } from '../../utils/actions';
109
import { RaidenError, ErrorCodes } from '../../utils/error';
11-
import { Hash } from '../../utils/types';
1210
import { transfer, transferExpire } from '../actions';
13-
import { Direction, TransferState } from '../state';
11+
import { Direction } from '../state';
1412
import { dispatchAndWait$ } from './utils';
1513

1614
/**
17-
* Predicate to check if a transfer has expired.
18-
*
19-
* For a transfer to expire it has to satisfy these conditions:
20-
*
21-
* - It must *not* have been unlocked.
22-
* - It must *not* have been expired before.
23-
* - The corresponding secret must not have been registered on-chain before the
24-
* lock's expiration.
25-
* - The channel must *not* be closed.
26-
*
27-
* @param transfer - TransferState to be checked
28-
* @param confirmationBlocks - Confirmation blocks config param
29-
* @param blockNumber - The current block number
30-
* @returns boolean if the transfer has expired
31-
*/
32-
function isTransferExpired(
33-
transfer: TransferState,
34-
confirmationBlocks: number,
35-
blockNumber: number,
36-
): boolean {
37-
return (
38-
!transfer.unlock &&
39-
!transfer.lockExpired &&
40-
!transfer.channelClosed &&
41-
transfer.transfer.lock.expiration.add(confirmationBlocks).lte(blockNumber) &&
42-
// don't expire if secret got registered before lock expired
43-
!transfer.secret?.registerBlock
44-
);
45-
}
46-
47-
/**
48-
* Contains the core logic of {@link transferAutoExpireEpic}.
49-
*
50-
* @param action$ - Observable of {@link RaidenAction} actions
51-
* @param state - Contains The current state of the app
52-
* @param config - Contains the current app config
53-
* @param config.confirmationBlocks - Confirmation blocks config param
54-
* @param blockNumber - The current block number
55-
* @returns Observable of {@link transferExpire.request} or {@link transfer.failure} actions
56-
*/
57-
function autoExpire$(
58-
action$: Observable<RaidenAction>,
59-
state: RaidenState,
60-
{ confirmationBlocks }: RaidenConfig,
61-
blockNumber: number,
62-
): Observable<transferExpire.request | transfer.failure> {
63-
// we can send LockExpired only for SENT transfers
64-
return from(Object.entries(state.sent) as Array<[Hash, typeof state.sent[string]]>).pipe(
65-
filter(([, sent]) => isTransferExpired(sent, confirmationBlocks, blockNumber)),
66-
mergeMap(([secrethash, sent]) => {
67-
const meta = { secrethash, direction: Direction.SENT };
68-
// this observable acts like a Promise: emits request once, completes on success/failure
69-
return merge(
70-
dispatchAndWait$(
71-
action$,
72-
transferExpire.request(undefined, meta),
73-
isResponseOf(transferExpire, meta),
74-
),
75-
// notify users that this transfer failed definitely
76-
of(
77-
transfer.failure(
78-
new RaidenError(ErrorCodes.XFER_EXPIRED, {
79-
block: sent.transfer.lock.expiration.toString(),
80-
}),
81-
meta,
82-
),
83-
),
84-
);
85-
}),
86-
);
87-
}
88-
89-
/**
90-
* Process newBlocks, emits transferExpire.request (request to compose&sign LockExpired for a transfer)
91-
* if pending transfer's lock expired and transfer didn't unlock (succeed) in time
15+
* Process newBlocks, emits transferExpire.request (request to compose&sign LockExpired for a
16+
* transfer) if pending transfer's lock expired and transfer didn't unlock (succeed) in time
9217
* Also, emits transfer.failure, to notify users that a transfer has failed (although it'll only be
9318
* considered as completed with fail once the transferExpireProcessed arrives).
9419
*
@@ -104,15 +29,47 @@ export const transferAutoExpireEpic = (
10429
{ config$ }: RaidenEpicDeps,
10530
): Observable<transferExpire.request | transfer.failure> =>
10631
action$.pipe(
107-
filter(isActionOf(newBlock)),
32+
filter(newBlock.is),
33+
pluck('payload', 'blockNumber'),
10834
withLatestFrom(state$, config$),
10935
// With interactive signing sending a lock expired message requires user
11036
// intervention. In that case it is possible for a new block to arrive
11137
// while waiting for the user permission, without the `exhaustMap` below
11238
// multiple signing requests would be emited *for the same lock*.
11339
// `exhaustMap` prevents that from happening, by blocking new signing
11440
// requests until the existing ones have been concluded.
115-
exhaustMap(([{ payload: { blockNumber } }, state, config]) =>
116-
autoExpire$(action$, state, config, blockNumber),
41+
exhaustMap(([blockNumber, { transfers }, { confirmationBlocks }]) =>
42+
from(
43+
Object.values(transfers).filter(
44+
(r) =>
45+
r.direction === Direction.SENT &&
46+
!r.unlock &&
47+
!r.expired &&
48+
!r.secretRegistered &&
49+
!r.channelClosed &&
50+
r.expiration <= blockNumber - confirmationBlocks * 2,
51+
),
52+
).pipe(
53+
mergeMap((doc) => {
54+
const meta = { secrethash: doc.transfer.lock.secrethash, direction: Direction.SENT };
55+
// this observable acts like a Promise: emits request once, completes on success/failure
56+
return merge(
57+
dispatchAndWait$(
58+
action$,
59+
transferExpire.request(undefined, meta),
60+
isResponseOf(transferExpire, meta),
61+
),
62+
// notify users that this transfer failed definitely
63+
of(
64+
transfer.failure(
65+
new RaidenError(ErrorCodes.XFER_EXPIRED, {
66+
block: doc.transfer.lock.expiration.toString(),
67+
}),
68+
meta,
69+
),
70+
),
71+
);
72+
}),
73+
),
11774
),
11875
);
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
export * from './close';
21
export * from './expire';
32
export * from './locked';
43
export * from './init';
54
export * from './mediate';
65
export * from './processed';
7-
export * from './refund';
86
export * from './retry';
97
export * from './secret';
108
export * from './withdraw';

0 commit comments

Comments
 (0)