raiden_state_machine/machine/
mediator.rs

1#![warn(clippy::missing_docs_in_private_items)]
2
3use std::iter;
4
5use num_traits::ToPrimitive;
6use raiden_primitives::{
7	constants::CANONICAL_IDENTIFIER_UNORDERED_QUEUE,
8	hashing::hash_secret,
9	types::{
10		Address,
11		BlockExpiration,
12		BlockHash,
13		BlockNumber,
14		BlockTimeout,
15		CanonicalIdentifier,
16		LockTimeout,
17		Secret,
18		SecretHash,
19		TokenAmount,
20	},
21};
22use rug::Rational;
23
24use super::{
25	channel,
26	routes,
27	secret_registry,
28	utils::{
29		self,
30		update_channel,
31	},
32};
33use crate::{
34	constants::{
35		PAYEE_STATE_SECRET_KNOWN,
36		PAYEE_STATE_TRANSFER_FINAL,
37		PAYEE_STATE_TRANSFER_PAID,
38		PAYER_STATE_SECRET_KNOWN,
39		PAYER_STATE_TRANSFER_FINAL,
40		PAYER_STATE_TRANSFER_PAID,
41	},
42	errors::StateTransitionError,
43	types::{
44		ActionInitMediator,
45		Block,
46		ChainState,
47		ChannelState,
48		ChannelStatus,
49		ContractReceiveSecretReveal,
50		ErrorUnexpectedReveal,
51		ErrorUnlockClaimFailed,
52		ErrorUnlockFailed,
53		Event,
54		FeeScheduleState,
55		HashTimeLockState,
56		Interpolate,
57		LockedTransferState,
58		MediationPairState,
59		MediatorTransferState,
60		PayeeState,
61		PayerState,
62		Random,
63		ReceiveLockExpired,
64		ReceiveSecretReveal,
65		ReceiveTransferRefund,
66		ReceiveUnlock,
67		SendMessageEventInner,
68		SendSecretReveal,
69		StateChange,
70		UnlockClaimSuccess,
71		UnlockSuccess,
72		WaitingTransferState,
73		WaitingTransferStatus,
74	},
75	views::{
76		self,
77		get_addresses_to_channels,
78	},
79};
80
81/// A transition result for the mediator state.
82pub(super) type TransitionResult = std::result::Result<MediatorTransition, StateTransitionError>;
83
84/// Mediator transition content.
85#[derive(Debug)]
86pub struct MediatorTransition {
87	pub new_state: Option<MediatorTransferState>,
88	pub chain_state: ChainState,
89	pub events: Vec<Event>,
90}
91
92/// Returns the channel of a given transfer pair or None if it's not found.
93pub(crate) fn get_channel(
94	chain_state: &ChainState,
95	canonical_identifier: CanonicalIdentifier,
96) -> Option<&ChannelState> {
97	views::get_channel_by_canonical_identifier(chain_state, canonical_identifier)
98}
99
100/// True if both transfers are for the same mediated transfer.
101fn is_send_transfer_almost_equal(
102	send: &LockedTransferState,
103	received: &LockedTransferState,
104) -> bool {
105	send.payment_identifier == received.payment_identifier &&
106		send.token == received.token &&
107		send.lock.expiration == received.lock.expiration &&
108		send.lock.secrethash == received.lock.secrethash &&
109		send.initiator == received.initiator &&
110		send.target == received.target
111}
112
113/// True if waiting is safe, i.e. there are more than enough blocks to safely
114/// unlock on chain.
115pub(super) fn is_safe_to_wait(
116	lock_expiration: BlockExpiration,
117	reveal_timeout: BlockTimeout,
118	block_number: BlockNumber,
119) -> Result<(), String> {
120	if lock_expiration < reveal_timeout {
121		return Err("Lock expiration must be larger than reveal timeout".to_owned())
122	}
123	let lock_timeout: LockTimeout = lock_expiration.saturating_sub(block_number.into()).into();
124	if lock_timeout > reveal_timeout {
125		return Ok(())
126	}
127
128	Err(format!(
129		"Lock timeout is unsafe. \
130         Timeout must be larger than {} but it is {}.\
131         expiration: {} block_number {}",
132		reveal_timeout, lock_timeout, lock_expiration, block_number
133	))
134}
135
136/// Returns the x value where both functions intersect
137///
138/// `fee_func` is a piecewise linear function while `line` is a straight line
139/// and takes the one of fee_func's indexes as argument.
140///
141/// Returns `None` if there is no intersection within `fee_func`s domain, which
142/// indicates a lack of capacity.
143fn find_intersection<LineFunc>(fee_func: Interpolate, line: LineFunc) -> Option<Rational>
144where
145	LineFunc: Fn(usize) -> Rational,
146{
147	let mut i = 0;
148	let mut y = fee_func.y_list[i].clone();
149	let compare = if y < line(i) { |x, y| -> bool { x < y } } else { |x, y| -> bool { x > y } };
150	while compare(y, line(i)) {
151		i += 1;
152		if i == fee_func.x_list.len() {
153			return None
154		}
155		y = fee_func.y_list[i].clone()
156	}
157
158	let x1 = fee_func.x_list[i - 1].clone();
159	let x2 = fee_func.x_list[i].clone();
160	let yf1 = fee_func.y_list[i - 1].clone();
161	let yf2 = fee_func.y_list[i].clone();
162	let yl1 = line(i - 1);
163	let yl2 = line(i);
164
165	Some((yl1.clone() - yf1.clone()) * (x2 - x1.clone()) / ((yf2 - yf1) - (yl2 - yl1)) + x1)
166}
167
168/// Return the amount after fees are taken.
169fn get_amount_without_fees(
170	amount_with_fees: TokenAmount,
171	channel_in: &ChannelState,
172	channel_out: &ChannelState,
173) -> Result<TokenAmount, String> {
174	let balance_in = views::channel_balance(&channel_in.our_state, &channel_in.partner_state);
175	let balance_out = views::channel_balance(&channel_out.our_state, &channel_out.partner_state);
176	let receivable =
177		channel_in.our_total_deposit() + channel_in.partner_total_deposit() - balance_in;
178
179	if channel_in.fee_schedule.cap_fees != channel_out.fee_schedule.cap_fees {
180		return Err(
181			"Both channels must have the same cap_fees setting for the same mediator".to_owned()
182		)
183	}
184
185	let fee_func = FeeScheduleState::mediation_fee_func(
186		channel_in.fee_schedule.clone(),
187		channel_out.fee_schedule.clone(),
188		balance_in,
189		balance_out,
190		receivable,
191		Some(amount_with_fees),
192		None,
193		channel_in.fee_schedule.cap_fees,
194	)?;
195	let amount_with_fees = Rational::from(amount_with_fees.as_u128());
196	if let Some(amount_without_fees) = find_intersection(fee_func.clone(), |i| {
197		amount_with_fees.clone() - fee_func.x_list[i].clone()
198	}) {
199		let amount_without_fees = TokenAmount::from(
200			amount_without_fees
201				.to_u128()
202				.ok_or("Could not convert rational to u128".to_owned())?,
203		);
204		Ok(amount_without_fees)
205	} else {
206		Err("Undefined mediation fee".to_owned())
207	}
208}
209
210/// Given a payer transfer tries the given route to proceed with the mediation.
211fn forward_transfer_pair(
212	chain_state: &mut ChainState,
213	payer_transfer: &LockedTransferState,
214	payer_channel: ChannelState,
215	mut payee_channel: ChannelState,
216	block_number: BlockNumber,
217) -> Result<(Option<MediationPairState>, Vec<Event>), String> {
218	let amount_after_fees =
219		get_amount_without_fees(payer_transfer.lock.amount, &payer_channel, &payee_channel)?;
220	let lock_timeout = payer_transfer.lock.expiration - block_number;
221	let safe_to_use_channel =
222		payee_channel.is_usable_for_mediation(amount_after_fees, lock_timeout);
223	if !safe_to_use_channel {
224		return Ok((None, vec![]))
225	}
226
227	if payee_channel.settle_timeout < lock_timeout {
228		return Err("Settle timeout must be >= lock timeout".to_owned())
229	}
230
231	let message_identifier = chain_state.pseudo_random_number_generator.next();
232	let recipient_address = payee_channel.partner_state.address;
233	let recipient_metadata =
234		views::get_address_metadata(recipient_address, payer_transfer.route_states.clone());
235	let (new_payee_channel, locked_transfer_event) = channel::send_locked_transfer(
236		payee_channel.clone(),
237		payer_transfer.initiator,
238		payer_transfer.target,
239		amount_after_fees,
240		payer_transfer.lock.expiration,
241		payer_transfer.secret.clone(),
242		payer_transfer.lock.secrethash,
243		message_identifier,
244		payer_transfer.payment_identifier,
245		payer_transfer.route_states.clone(),
246		recipient_metadata,
247	)?;
248	payee_channel = new_payee_channel;
249	update_channel(chain_state, payee_channel.clone())?;
250
251	let locked_transfer = locked_transfer_event.transfer.clone();
252	let mediated_events = vec![locked_transfer_event.into()];
253
254	let transfer_pair = MediationPairState {
255		payer_transfer: payer_transfer.clone(),
256		payee_address: payee_channel.partner_state.address,
257		payee_transfer: locked_transfer,
258		payer_state: PayerState::Pending,
259		payee_state: PayeeState::Pending,
260	};
261
262	Ok((Some(transfer_pair), mediated_events))
263}
264
265/// Try a new route or fail back to a refund.
266///
267/// The mediator can safely try a new route knowing that the tokens from
268/// payer_transfer will cover the expenses of the mediation. If there is no
269/// route available that may be used at the moment of the call the mediator may
270/// send a refund back to the payer, allowing the payer to try a different
271/// route.
272fn mediate_transfer(
273	mut chain_state: ChainState,
274	mut mediator_state: MediatorTransferState,
275	payer_channel: &ChannelState,
276	payer_transfer: LockedTransferState,
277	block_number: BlockNumber,
278) -> TransitionResult {
279	if Some(payer_channel.partner_state.address) != payer_transfer.balance_proof.sender {
280		return Err(StateTransitionError { msg: "Transfer must be signed by sender".to_owned() })
281	}
282
283	let our_address = payer_channel.our_state.address;
284	// Makes sure we filter routes that have already been used.
285	//
286	// So in a setup like this, we want to make sure that node 2, having tried to
287	// route the transfer through 3 will also try 5 before sending it backwards to 1
288	//
289	// 1 -> 2 -> 3 -> 4
290	//      v         ^
291	//      5 -> 6 -> 7
292	let candidate_route_states = routes::filter_acceptable_routes(
293		mediator_state.routes.clone(),
294		mediator_state.refunded_channels.clone(),
295		get_addresses_to_channels(&chain_state),
296		payer_channel.canonical_identifier.token_network_address,
297		our_address,
298	);
299
300	let default_token_network_address = payer_channel.canonical_identifier.token_network_address;
301	for route_state in candidate_route_states {
302		let next_hop = match route_state.hop_after(our_address) {
303			Some(next_hop) => next_hop,
304			None => continue,
305		};
306		let target_token_network =
307			route_state.swaps.get(&our_address).unwrap_or(&default_token_network_address);
308		let payee_channel = match views::get_channel_by_token_network_and_partner(
309			&chain_state,
310			*target_token_network,
311			next_hop,
312		) {
313			Some(channel) => channel.clone(),
314			None => continue,
315		};
316
317		let (mediation_transfer_pair, mediation_events) = forward_transfer_pair(
318			&mut chain_state,
319			&payer_transfer,
320			payer_channel.clone(),
321			payee_channel,
322			block_number,
323		)
324		.map_err(Into::into)?;
325		if let Some(mediation_transfer_pair) = mediation_transfer_pair {
326			mediator_state.transfers_pair.push(mediation_transfer_pair);
327			return Ok(MediatorTransition {
328				new_state: Some(mediator_state),
329				chain_state,
330				events: mediation_events,
331			})
332		}
333	}
334
335	mediator_state.waiting_transfer = Some(WaitingTransferState {
336		transfer: payer_transfer,
337		status: WaitingTransferStatus::Waiting,
338	});
339	Ok(MediatorTransition { new_state: Some(mediator_state), chain_state, events: vec![] })
340}
341
342/// If it's known the secret is registered on-chain, the node should not send
343/// a new transaction. Note there is a race condition:
344///
345/// - Node B learns the secret on-chain, sends a secret reveal to A
346/// - Node A receives the secret reveal off-chain prior to the event for the secret registration, if
347///   the lock is in the danger zone A will try to register the secret on-chain, because from its
348///   perspective the secret is not there yet.
349fn has_secret_registration_started(
350	channel_states: Vec<&ChannelState>,
351	transfers_pair: &[MediationPairState],
352	secrethash: SecretHash,
353) -> bool {
354	let is_secret_registered_onchain = channel_states
355		.iter()
356		.any(|channel_state| channel_state.partner_state.secret_known_onchain(secrethash));
357
358	let has_pending_transaction = transfers_pair
359		.iter()
360		.any(|pair| pair.payer_state == PayerState::WaitingSecretReveal);
361
362	is_secret_registered_onchain || has_pending_transaction
363}
364
365/// Clear the channels which have expired locks.
366///
367/// This only considers the *sent* transfers, received transfers can only be
368/// updated by the partner.
369fn events_to_remove_expired_locks(
370	chain_state: &mut ChainState,
371	mediator_state: &mut MediatorTransferState,
372	block_number: BlockNumber,
373) -> Result<Vec<Event>, String> {
374	let mut events = vec![];
375
376	if mediator_state.transfers_pair.is_empty() {
377		return Ok(events)
378	}
379
380	let initial_payer_transfer = mediator_state.transfers_pair[0].payer_transfer.clone();
381	for transfer_pair in mediator_state.transfers_pair.iter_mut() {
382		let balance_proof = &transfer_pair.payee_transfer.balance_proof;
383		let channel_identifier = balance_proof.canonical_identifier.clone();
384		let channel_state =
385			match views::get_channel_by_canonical_identifier(chain_state, channel_identifier) {
386				Some(channel_state) => channel_state.clone(),
387				None => return Ok(events),
388			};
389
390		let secrethash = mediator_state.secrethash;
391		let mut lock: Option<HashTimeLockState> = None;
392		if let Some(locked_lock) =
393			channel_state.our_state.secrethashes_to_lockedlocks.get(&secrethash)
394		{
395			if !channel_state.our_state.secrethashes_to_unlockedlocks.contains_key(&secrethash) {
396				lock = Some(locked_lock.clone());
397			}
398		} else if let Some(unlocked_lock) =
399			channel_state.our_state.secrethashes_to_unlockedlocks.get(&secrethash)
400		{
401			lock = Some(unlocked_lock.lock.clone());
402		}
403
404		if let Some(lock) = lock {
405			let lock_expiration_threshold =
406				channel::views::get_sender_expiration_threshold(lock.expiration);
407			let has_lock_expired = channel::validators::is_lock_expired(
408				&channel_state.our_state,
409				&lock,
410				block_number,
411				lock_expiration_threshold,
412			)
413			.is_ok();
414			let is_channel_open = channel_state.status() == ChannelStatus::Opened;
415			let payee_address_metadata = views::get_address_metadata(
416				transfer_pair.payee_address,
417				initial_payer_transfer.route_states.clone(),
418			);
419
420			if has_lock_expired && is_channel_open {
421				transfer_pair.payee_state = PayeeState::Expired;
422				let (channel_state, expired_lock_events) = channel::send_lock_expired(
423					channel_state,
424					lock,
425					&mut chain_state.pseudo_random_number_generator,
426					payee_address_metadata,
427				)?;
428				utils::update_channel(chain_state, channel_state)?;
429				events.extend(expired_lock_events.into_iter().map(Event::SendLockExpired));
430				events.push(
431					ErrorUnlockFailed {
432						identifier: transfer_pair.payee_transfer.payment_identifier,
433						secrethash,
434						reason: "Lock expired".to_owned(),
435					}
436					.into(),
437				)
438			}
439		}
440	}
441
442	Ok(events)
443}
444
445/// Reveal the secret off-chain.
446///
447/// The secret is revealed off-chain even if there is a pending transaction to
448/// reveal it on-chain, this allows the unlock to happen off-chain, which is
449/// faster.
450///
451/// This node is named N, suppose there is a mediated transfer with two refund
452/// transfers, one from B and one from C:
453///
454/// A-N-B...B-N-C..C-N-D
455///
456/// Under normal operation N will first learn the secret from D, then reveal to
457/// C, wait for C to inform the secret is known before revealing it to B, and
458/// again wait for B before revealing the secret to A.
459///
460/// If B somehow sent a reveal secret before C and D, then the secret will be
461/// revealed to A, but not C and D, meaning the secret won't be propagated
462/// forward. Even if D sent a reveal secret at about the same time, the secret
463/// will only be revealed to B upon confirmation from C.
464///
465/// If the proof doesn't arrive in time and the lock's expiration is at risk, N
466/// won't lose tokens since it knows the secret can go on-chain at any time.
467fn events_for_secret_reveal(
468	transfers_pair: &mut [MediationPairState],
469	secret: Secret,
470	pseudo_random_number_generator: &mut Random,
471) -> Vec<Event> {
472	let mut events = vec![];
473
474	for pair in transfers_pair.iter_mut().rev() {
475		let payee_knows_secret = PAYEE_STATE_SECRET_KNOWN.contains(&pair.payee_state);
476		let payer_knows_secret = PAYER_STATE_SECRET_KNOWN.contains(&pair.payer_state);
477		let is_transfer_pending = pair.payer_state == PayerState::Pending;
478		let should_send_secret = payee_knows_secret && !payer_knows_secret && is_transfer_pending;
479
480		if should_send_secret {
481			let message_identifier = pseudo_random_number_generator.next();
482			pair.payer_state = PayerState::SecretRevealed;
483			let payer_transfer = &pair.payer_transfer;
484			let recipient = payer_transfer.balance_proof.sender.expect("Should be set");
485			let reveal_secret = SendSecretReveal {
486				inner: SendMessageEventInner {
487					recipient,
488					recipient_metadata: views::get_address_metadata(
489						recipient,
490						payer_transfer.route_states.clone(),
491					),
492					canonical_identifier: CANONICAL_IDENTIFIER_UNORDERED_QUEUE,
493					message_identifier,
494				},
495				secret: secret.clone(),
496				secrethash: SecretHash::from_slice(&hash_secret(&secret.0)),
497			};
498			events.push(reveal_secret.into());
499		}
500	}
501
502	events
503}
504
505/// Returns a list of events to send unlock While it's safe do the off-chain unlock."""
506fn events_for_balance_proof(
507	chain_state: &mut ChainState,
508	transfers_pair: &mut [MediationPairState],
509	secret: Secret,
510	secrethash: SecretHash,
511) -> Vec<Event> {
512	let mut events = vec![];
513
514	for pair in transfers_pair.iter_mut().rev() {
515		let payee_knows_secret = PAYEE_STATE_SECRET_KNOWN.contains(&pair.payee_state);
516		let payee_paid = PAYEE_STATE_TRANSFER_PAID.contains(&pair.payee_state);
517
518		let mut payee_channel = match get_channel(
519			chain_state,
520			pair.payee_transfer.balance_proof.canonical_identifier.clone(),
521		) {
522			Some(payee_channel) => payee_channel.clone(),
523			None => continue,
524		};
525		let payer_channel = match get_channel(
526			chain_state,
527			pair.payer_transfer.balance_proof.canonical_identifier.clone(),
528		) {
529			Some(payer_channel) => payer_channel,
530			None => continue,
531		};
532
533		let payee_channel_open = payee_channel.status() == ChannelStatus::Opened;
534
535		// The mediator must not send to the payee a balance proof if the lock
536		// is in the danger zone, because the payer may not do the same and the
537		// on-chain unlock may fail. If the lock is nearing it's expiration
538		// block, then on-chain unlock should be done, and if successful it can
539		// be unlocked off-chain.
540		let mut is_safe_to_send_balance_proof = false;
541		if is_safe_to_wait(
542			pair.payer_transfer.lock.expiration,
543			payer_channel.reveal_timeout,
544			chain_state.block_number,
545		)
546		.is_ok()
547		{
548			is_safe_to_send_balance_proof = true;
549		}
550
551		let should_send_balance_proof_to_payee = payee_channel_open &&
552			payee_knows_secret &&
553			!payee_paid && is_safe_to_send_balance_proof;
554
555		if should_send_balance_proof_to_payee {
556			pair.payee_state = PayeeState::BalanceProof;
557
558			let message_identifier = chain_state.pseudo_random_number_generator.next();
559			let recipient_address = pair.payee_address;
560			let recipient_metadata = views::get_address_metadata(
561				recipient_address,
562				pair.payee_transfer.route_states.clone(),
563			);
564			if let Ok(unlock_lock) = channel::send_unlock(
565				&mut payee_channel,
566				message_identifier,
567				pair.payee_transfer.payment_identifier,
568				secret.clone(),
569				secrethash,
570				chain_state.block_number,
571				recipient_metadata,
572			) {
573				let _ = update_channel(chain_state, payee_channel.clone());
574				events.push(unlock_lock.into());
575				events.push(
576					UnlockSuccess {
577						identifier: pair.payer_transfer.payment_identifier,
578						secrethash: pair.payer_transfer.lock.secrethash,
579					}
580					.into(),
581				)
582			}
583		}
584	}
585
586	events
587}
588
589/// Register the secret on-chain if the payer channel is already closed and
590/// the mediator learned the secret off-chain.
591///
592/// Balance proofs are not exchanged for closed channels, so there is no reason
593/// to wait for the unsafe region to register secret.
594///
595/// Note:
596///
597/// If the secret is learned before the channel is closed, then the channel
598/// will register the secrets in bulk, not the transfer.
599fn events_for_onchain_secretreveal_if_closed(
600	chain_state: &ChainState,
601	transfers_pair: &mut [MediationPairState],
602	secret: Secret,
603	secrethash: SecretHash,
604	block_hash: BlockHash,
605) -> Vec<Event> {
606	let mut events = vec![];
607
608	let mut all_payer_channels = vec![];
609	for transfer_pair in transfers_pair.iter() {
610		if let Some(channel_state) = get_channel(
611			chain_state,
612			transfer_pair.payer_transfer.balance_proof.canonical_identifier.clone(),
613		) {
614			all_payer_channels.push(channel_state);
615		}
616	}
617
618	let mut transaction_sent =
619		has_secret_registration_started(all_payer_channels, transfers_pair, secrethash);
620
621	let pending_transfers = transfers_pair.iter_mut().filter(|pair| {
622		!PAYEE_STATE_TRANSFER_FINAL.contains(&pair.payee_state) ||
623			!PAYER_STATE_TRANSFER_FINAL.contains(&pair.payer_state)
624	});
625	for pending_pair in pending_transfers {
626		let payer_channel = match get_channel(
627			chain_state,
628			pending_pair.payer_transfer.balance_proof.canonical_identifier.clone(),
629		) {
630			Some(payer_channel) => payer_channel,
631			None => continue,
632		};
633
634		if payer_channel.status() == ChannelStatus::Closed {
635			pending_pair.payer_state = PayerState::WaitingSecretReveal;
636
637			if !transaction_sent {
638				if let Some(lock) =
639					channel::views::get_lock(&payer_channel.partner_state, secrethash)
640				{
641					let reveal_events = secret_registry::events_for_onchain_secretreveal(
642						payer_channel,
643						secret.clone(),
644						lock.expiration,
645						block_hash,
646					);
647
648					events.extend(reveal_events);
649					transaction_sent = true;
650				}
651			}
652		}
653	}
654
655	events
656}
657
658/// Reveal the secret on-chain if the lock enters the unsafe region and the
659/// secret is not yet on-chain.
660fn events_for_onchain_secretreveal_if_dangerzone(
661	chain_state: &ChainState,
662	transfers_pair: &mut [MediationPairState],
663	secrethash: SecretHash,
664	block_number: BlockNumber,
665	block_hash: BlockHash,
666) -> Result<Vec<Event>, String> {
667	let mut events = vec![];
668
669	let mut all_payer_channels = vec![];
670	for transfer_pair in transfers_pair.iter() {
671		if let Some(channel_state) = get_channel(
672			chain_state,
673			transfer_pair.payer_transfer.balance_proof.canonical_identifier.clone(),
674		) {
675			all_payer_channels.push(channel_state);
676		}
677	}
678
679	let mut transaction_sent =
680		has_secret_registration_started(all_payer_channels, transfers_pair, secrethash);
681
682	// Only consider the transfers which have a pair. This means if we have a
683	// waiting transfer and for some reason the node knows the secret, it will
684	// not try to register it. Otherwise it would be possible for an attacker to
685	// reveal the secret late, just to force the node to send an unnecessary
686	// transaction.
687
688	let pending_transfers = transfers_pair.iter_mut().filter(|pair| {
689		!PAYEE_STATE_TRANSFER_FINAL.contains(&pair.payee_state) ||
690			!PAYER_STATE_TRANSFER_FINAL.contains(&pair.payer_state)
691	});
692	for pair in pending_transfers {
693		let payer_channel = match get_channel(
694			chain_state,
695			pair.payer_transfer.balance_proof.canonical_identifier.clone(),
696		) {
697			Some(payer_channel) => payer_channel,
698			None => continue,
699		};
700
701		let lock = &pair.payer_transfer.lock;
702		let safe_to_wait =
703			is_safe_to_wait(lock.expiration, payer_channel.reveal_timeout, block_number).is_ok();
704		let secret_known =
705			payer_channel.partner_state.is_secret_known(pair.payer_transfer.lock.secrethash);
706
707		if !safe_to_wait && secret_known {
708			pair.payer_state = PayerState::WaitingSecretReveal;
709
710			if !transaction_sent {
711				let secret = match payer_channel.partner_state.get_secret(lock.secrethash) {
712					Some(secret) => secret,
713					None => return Err("The secret should be known at this point".to_owned()),
714				};
715
716				let reveal_events = secret_registry::events_for_onchain_secretreveal(
717					payer_channel,
718					secret,
719					lock.expiration,
720					block_hash,
721				);
722
723				events.extend(reveal_events);
724
725				transaction_sent = true;
726			}
727		}
728	}
729
730	Ok(events)
731}
732
733/// Informational events for expired locks.
734fn events_for_expired_pairs(
735	chain_state: &ChainState,
736	transfers_pair: &mut [MediationPairState],
737	waiting_transfer: &mut Option<WaitingTransferState>,
738	block_number: BlockNumber,
739) -> Vec<Event> {
740	let mut events = vec![];
741
742	let pending_transfers = transfers_pair.iter_mut().filter(|pair| {
743		!PAYEE_STATE_TRANSFER_FINAL.contains(&pair.payee_state) ||
744			!PAYER_STATE_TRANSFER_FINAL.contains(&pair.payer_state)
745	});
746	for pair in pending_transfers {
747		let payer_channel = match get_channel(
748			chain_state,
749			pair.payer_transfer.balance_proof.canonical_identifier.clone(),
750		) {
751			Some(payer_channel) => payer_channel,
752			None => continue,
753		};
754		let has_payer_transfer_expired = channel::validators::is_transfer_expired(
755			&pair.payer_transfer,
756			payer_channel,
757			block_number,
758		);
759
760		if has_payer_transfer_expired {
761			pair.payer_state = PayerState::Expired;
762			let unlock_claim_failed = ErrorUnlockClaimFailed {
763				identifier: pair.payer_transfer.payment_identifier,
764				secrethash: pair.payer_transfer.lock.secrethash,
765				reason: "Lock expired".to_owned(),
766			};
767			events.push(unlock_claim_failed.into());
768		}
769	}
770
771	if let Some(waiting_transfer) = waiting_transfer {
772		let expiration_threshold = channel::views::get_receiver_expiration_threshold(
773			waiting_transfer.transfer.lock.expiration,
774		);
775		let should_waiting_transfer_expire = waiting_transfer.status !=
776			WaitingTransferStatus::Expired &&
777			expiration_threshold <= block_number;
778		if should_waiting_transfer_expire {
779			waiting_transfer.status = WaitingTransferStatus::Expired;
780
781			let unlock_claim_failed = ErrorUnlockClaimFailed {
782				identifier: waiting_transfer.transfer.payment_identifier,
783				secrethash: waiting_transfer.transfer.lock.secrethash,
784				reason: "Lock expired".to_owned(),
785			};
786			events.push(unlock_claim_failed.into());
787		}
788	}
789
790	events
791}
792
793/// Set the secret to all mediated transfers.
794fn set_offchain_secret(
795	chain_state: &mut ChainState,
796	mediator_state: &mut MediatorTransferState,
797	secret: Secret,
798	secrethash: SecretHash,
799) -> Vec<Event> {
800	mediator_state.secret = Some(secret.clone());
801
802	for pair in &mediator_state.transfers_pair {
803		if let Some(payer_channel) =
804			get_channel(chain_state, pair.payer_transfer.balance_proof.canonical_identifier.clone())
805		{
806			let mut payer_channel = payer_channel.clone();
807			channel::register_offchain_secret(&mut payer_channel, secret.clone(), secrethash);
808			let _ = update_channel(chain_state, payer_channel);
809		}
810		if let Some(payee_channel) =
811			get_channel(chain_state, pair.payee_transfer.balance_proof.canonical_identifier.clone())
812		{
813			let mut payee_channel = payee_channel.clone();
814			channel::register_offchain_secret(&mut payee_channel, secret.clone(), secrethash);
815			let _ = update_channel(chain_state, payee_channel);
816		}
817	}
818	// The secret should never be revealed if `waiting_transfer` is not None.
819	// For this to happen this node must have received a transfer, which it did
820	// *not* mediate, and nevertheless the secret was revealed.
821	//
822	// This can only be possible if the initiator reveals the secret without the
823	// target's secret request, or if the node which sent the `waiting_transfer`
824	// has sent another transfer which reached the target (meaning someone along
825	// the path will lose tokens).
826	if let Some(waiting_transfer) = &mediator_state.waiting_transfer {
827		if let Some(payer_channel) = get_channel(
828			chain_state,
829			waiting_transfer.transfer.balance_proof.canonical_identifier.clone(),
830		) {
831			let mut payer_channel = payer_channel.clone();
832			channel::register_offchain_secret(&mut payer_channel, secret, secrethash);
833			let _ = update_channel(chain_state, payer_channel);
834
835			let unexpected_reveal = ErrorUnexpectedReveal {
836				secrethash,
837				reason: "The mediator has a waiting transfer".to_owned(),
838			};
839
840			return vec![unexpected_reveal.into()]
841		}
842	}
843
844	vec![]
845}
846
847/// Set the state of a transfer *sent* to a payee.
848fn set_offchain_reveal_state(transfers_pair: &mut Vec<MediationPairState>, payee_address: Address) {
849	for pair in transfers_pair {
850		if pair.payee_address == payee_address {
851			pair.payee_state = PayeeState::SecretRevealed;
852		}
853	}
854}
855
856/// Set the secret to all mediated transfers.
857/// The secret should have been learned from the secret registry.
858fn set_onchain_secret(
859	chain_state: &mut ChainState,
860	mediator_state: &mut MediatorTransferState,
861	secret: Secret,
862	secrethash: SecretHash,
863	block_number: BlockNumber,
864) -> Vec<Event> {
865	mediator_state.secret = Some(secret.clone());
866
867	for pair in &mediator_state.transfers_pair {
868		if let Some(payer_channel) =
869			get_channel(chain_state, pair.payer_transfer.balance_proof.canonical_identifier.clone())
870		{
871			let mut payer_channel = payer_channel.clone();
872			channel::register_onchain_secret(
873				&mut payer_channel,
874				secret.clone(),
875				secrethash,
876				block_number,
877				true,
878			);
879			let _ = update_channel(chain_state, payer_channel);
880		}
881		if let Some(payee_channel) =
882			get_channel(chain_state, pair.payee_transfer.balance_proof.canonical_identifier.clone())
883		{
884			let mut payee_channel = payee_channel.clone();
885			channel::register_onchain_secret(
886				&mut payee_channel,
887				secret.clone(),
888				secrethash,
889				block_number,
890				true,
891			);
892			let _ = update_channel(chain_state, payee_channel);
893		}
894	}
895
896	// Like the off-chain secret reveal, the secret should never be revealed
897	// on-chain if there is a waiting transfer.
898	if let Some(waiting_transfer) = &mediator_state.waiting_transfer {
899		if let Some(payer_channel) = get_channel(
900			chain_state,
901			waiting_transfer.transfer.balance_proof.canonical_identifier.clone(),
902		) {
903			let mut payer_channel = payer_channel.clone();
904			channel::register_onchain_secret(
905				&mut payer_channel,
906				secret,
907				secrethash,
908				block_number,
909				true,
910			);
911			let _ = update_channel(chain_state, payer_channel);
912
913			let unexpected_reveal = ErrorUnexpectedReveal {
914				secrethash,
915				reason: "The mediator has a waiting transfer".to_owned(),
916			};
917
918			return vec![unexpected_reveal.into()]
919		}
920	}
921
922	vec![]
923}
924
925/// Unlock the payee lock, reveal the lock to the payer, and if necessary
926/// register the secret on-chain.
927fn secret_learned(
928	mut chain_state: ChainState,
929	mut mediator_state: MediatorTransferState,
930	secret: Secret,
931	secrethash: SecretHash,
932	payee_address: Address,
933) -> TransitionResult {
934	let secret_reveal_events =
935		set_offchain_secret(&mut chain_state, &mut mediator_state, secret.clone(), secrethash);
936	set_offchain_reveal_state(&mut mediator_state.transfers_pair, payee_address);
937
938	let block_hash = chain_state.block_hash;
939	let onchain_secret_reveal = events_for_onchain_secretreveal_if_closed(
940		&chain_state,
941		&mut mediator_state.transfers_pair,
942		secret.clone(),
943		secrethash,
944		block_hash,
945	);
946
947	let offchain_secret_reveal = events_for_secret_reveal(
948		&mut mediator_state.transfers_pair,
949		secret.clone(),
950		&mut chain_state.pseudo_random_number_generator,
951	);
952
953	let balance_proof = events_for_balance_proof(
954		&mut chain_state,
955		&mut mediator_state.transfers_pair,
956		secret,
957		secrethash,
958	);
959
960	let mut events = vec![];
961	events.extend(secret_reveal_events);
962	events.extend(onchain_secret_reveal);
963	events.extend(offchain_secret_reveal);
964	events.extend(balance_proof);
965
966	Ok(MediatorTransition { new_state: Some(mediator_state), chain_state, events })
967}
968
969/// After Raiden learns about a new block this function must be called to
970/// handle expiration of the hash time locks.
971fn handle_block(
972	chain_state: ChainState,
973	mediator_state: Option<MediatorTransferState>,
974	state_change: Block,
975) -> TransitionResult {
976	let mediator_state = match mediator_state {
977		Some(mediator_state) => mediator_state,
978		None =>
979			return Err("Block should be accompanied by a valid mediator state".to_owned().into()),
980	};
981	let mut events = vec![];
982
983	let mut new_mediator_state = mediator_state;
984	let mut new_chain_state = chain_state;
985	if let Some(waiting_transfer) = new_mediator_state.waiting_transfer.clone() {
986		let secrethash = waiting_transfer.transfer.lock.secrethash;
987		let payer_channel_identifier =
988			waiting_transfer.transfer.balance_proof.canonical_identifier.clone();
989
990		if let Some(payer_channel) = views::get_channel_by_canonical_identifier(
991			&new_chain_state.clone(),
992			payer_channel_identifier,
993		) {
994			let mediation_attempt = mediate_transfer(
995				new_chain_state.clone(),
996				new_mediator_state.clone(),
997				payer_channel,
998				waiting_transfer.transfer,
999				state_change.block_number,
1000			)?;
1001
1002			if let Some(mut mediator_state) = mediation_attempt.new_state {
1003				events.extend(mediation_attempt.events);
1004
1005				let mediation_happened = events.iter().any(|event| {
1006					if let Event::SendLockedTransfer(e) = event {
1007						return e.transfer.lock.secrethash == secrethash
1008					}
1009					false
1010				});
1011				if mediation_happened {
1012					mediator_state.waiting_transfer = None;
1013				}
1014				new_mediator_state = mediator_state;
1015				new_chain_state = mediation_attempt.chain_state;
1016			}
1017		}
1018	}
1019
1020	events.extend(
1021		events_to_remove_expired_locks(
1022			&mut new_chain_state,
1023			&mut new_mediator_state,
1024			state_change.block_number,
1025		)
1026		.map_err(Into::into)?,
1027	);
1028	events.extend(
1029		events_for_onchain_secretreveal_if_dangerzone(
1030			&new_chain_state,
1031			&mut new_mediator_state.transfers_pair,
1032			new_mediator_state.secrethash,
1033			state_change.block_number,
1034			state_change.block_hash,
1035		)
1036		.map_err(Into::into)?,
1037	);
1038	events.extend(events_for_expired_pairs(
1039		&new_chain_state,
1040		&mut new_mediator_state.transfers_pair,
1041		&mut new_mediator_state.waiting_transfer,
1042		state_change.block_number,
1043	));
1044
1045	Ok(MediatorTransition {
1046		new_state: Some(new_mediator_state),
1047		chain_state: new_chain_state,
1048		events,
1049	})
1050}
1051
1052/// Handle a newly received mediated transfer.
1053fn handle_init(mut chain_state: ChainState, state_change: ActionInitMediator) -> TransitionResult {
1054	let from_transfer = state_change.from_transfer;
1055	let mut payer_channel =
1056		match get_channel(&chain_state, from_transfer.balance_proof.canonical_identifier.clone()) {
1057			Some(channel) => channel.clone(),
1058			None => return Ok(MediatorTransition { new_state: None, chain_state, events: vec![] }),
1059		};
1060
1061	let mediator_state = MediatorTransferState {
1062		secrethash: from_transfer.lock.secrethash,
1063		routes: state_change.candidate_route_states,
1064		refunded_channels: vec![],
1065		secret: None,
1066		transfers_pair: vec![],
1067		waiting_transfer: None,
1068	};
1069
1070	let mut events = vec![];
1071	let payer_address_metadata = match from_transfer.balance_proof.sender {
1072		Some(sender) => views::get_address_metadata(sender, from_transfer.route_states.clone()),
1073		None => None,
1074	};
1075	match channel::handle_receive_locked_transfer(
1076		&mut payer_channel,
1077		from_transfer.clone(),
1078		payer_address_metadata,
1079	) {
1080		Ok(locked_transfer_event) => {
1081			utils::update_channel(&mut chain_state, payer_channel.clone()).map_err(Into::into)?;
1082			events.push(locked_transfer_event);
1083		},
1084		Err((_error, locked_transfer_error_events)) =>
1085			return Ok(MediatorTransition {
1086				new_state: Some(mediator_state),
1087				chain_state,
1088				events: locked_transfer_error_events,
1089			}),
1090	};
1091
1092	let block_number = chain_state.block_number;
1093	let iteration =
1094		mediate_transfer(chain_state, mediator_state, &payer_channel, from_transfer, block_number)?;
1095	events.extend(iteration.events);
1096
1097	Ok(MediatorTransition {
1098		new_state: iteration.new_state,
1099		chain_state: iteration.chain_state,
1100		events,
1101	})
1102}
1103
1104/// Validate and handle a ReceiveTransferRefund mediator_state change.
1105/// A node might participate in mediated transfer more than once because of
1106/// refund transfers, e.g. A-B-C-B-D-T, B tried to mediate the transfer through
1107/// C, which didn't have an available route to proceed and refunds B, at this
1108/// point B is part of the path again and will try a new partner to proceed
1109/// with the mediation through D, D finally reaches the target T.
1110/// In the above scenario B has two pairs of payer and payee transfers:
1111///     payer:A payee:C from the first SendLockedTransfer
1112///     payer:C payee:D from the following SendRefundTransfer
1113fn handle_refund_transfer(
1114	mut chain_state: ChainState,
1115	mediator_state: Option<MediatorTransferState>,
1116	state_change: ReceiveTransferRefund,
1117) -> TransitionResult {
1118	let mut mediator_state = match mediator_state {
1119		Some(mediator_state) => mediator_state,
1120		None =>
1121			return Err("ReceiveTransferRefund should be accompanied by a valid mediator state"
1122				.to_owned()
1123				.into()),
1124	};
1125
1126	if mediator_state.secret.is_none() {
1127		return Ok(MediatorTransition {
1128			new_state: Some(mediator_state),
1129			chain_state,
1130			events: vec![],
1131		})
1132	}
1133
1134	if mediator_state.transfers_pair.is_empty() {
1135		return Ok(MediatorTransition {
1136			new_state: Some(mediator_state),
1137			chain_state,
1138			events: vec![],
1139		})
1140	}
1141
1142	// The last sent transfer is the only one that may be refunded, all the
1143	// previous ones are refunded already.
1144	let transfer_pair = mediator_state.transfers_pair.last().expect("Checked above");
1145	let payee_transfer = transfer_pair.payee_transfer.clone();
1146	let payer_transfer = transfer_pair.payer_transfer.clone();
1147	let canonical_identifier = payer_transfer.balance_proof.canonical_identifier.clone();
1148	let mut payer_channel = match get_channel(&chain_state, canonical_identifier) {
1149		Some(channel) => channel.clone(),
1150		None =>
1151			return Ok(MediatorTransition {
1152				new_state: Some(mediator_state),
1153				chain_state,
1154				events: vec![],
1155			}),
1156	};
1157
1158	let refund_transfer_event =
1159		match channel::handle_refund_transfer(&mut payer_channel, payee_transfer, state_change) {
1160			Ok(event) => event,
1161			Err(_) =>
1162				return Ok(MediatorTransition {
1163					new_state: Some(mediator_state),
1164					chain_state,
1165					events: vec![],
1166				}),
1167		};
1168
1169	update_channel(&mut chain_state, payer_channel.clone()).map_err(Into::into)?;
1170	mediator_state
1171		.refunded_channels
1172		.push(payer_channel.canonical_identifier.channel_identifier);
1173
1174	let block_number = chain_state.block_number;
1175	let iteration = mediate_transfer(
1176		chain_state,
1177		mediator_state,
1178		&payer_channel,
1179		payer_transfer,
1180		block_number,
1181	)?;
1182
1183	let mut events = vec![refund_transfer_event];
1184	events.extend(iteration.events);
1185
1186	Ok(MediatorTransition {
1187		new_state: iteration.new_state,
1188		chain_state: iteration.chain_state,
1189		events,
1190	})
1191}
1192
1193/// Handles the secret reveal and sends SendUnlock/RevealSecret if necessary.
1194fn handle_offchain_secret_reveal(
1195	chain_state: ChainState,
1196	mediator_state: Option<MediatorTransferState>,
1197	state_change: ReceiveSecretReveal,
1198) -> TransitionResult {
1199	let mediator_state = match mediator_state {
1200		Some(mediator_state) => mediator_state,
1201		None =>
1202			return Err("ReceiveSecretReveal should be accompanied by a valid mediator state"
1203				.to_owned()
1204				.into()),
1205	};
1206
1207	let is_valid = utils::is_valid_secret_reveal(&state_change, mediator_state.secrethash);
1208	let is_secret_unknown = mediator_state.secret.is_none();
1209
1210	if mediator_state.transfers_pair.is_empty() {
1211		// This will not happen during normal operation, but attackers might
1212		// send weird messages.
1213		return Ok(MediatorTransition {
1214			new_state: Some(mediator_state),
1215			chain_state,
1216			events: vec![],
1217		})
1218	}
1219
1220	// a SecretReveal should be rejected if the payer transfer
1221	// has expired. To check for this, we use the last
1222	// transfer pair.
1223	let transfer_pair = mediator_state.transfers_pair.last().expect("Should exist");
1224	let payer_transfer = &transfer_pair.payer_transfer;
1225	let canonical_identifier = payer_transfer.balance_proof.canonical_identifier.clone();
1226	let payer_channel = match get_channel(&chain_state, canonical_identifier) {
1227		Some(channel) => channel,
1228		None =>
1229			return Ok(MediatorTransition {
1230				new_state: Some(mediator_state),
1231				chain_state,
1232				events: vec![],
1233			}),
1234	};
1235
1236	let has_payer_transfer_expired = channel::validators::is_transfer_expired(
1237		payer_transfer,
1238		payer_channel,
1239		chain_state.block_number,
1240	);
1241
1242	if is_secret_unknown && is_valid && !has_payer_transfer_expired {
1243		return secret_learned(
1244			chain_state,
1245			mediator_state,
1246			state_change.secret,
1247			state_change.secrethash,
1248			state_change.sender,
1249		)
1250	}
1251
1252	Ok(MediatorTransition { new_state: Some(mediator_state), chain_state, events: vec![] })
1253}
1254
1255/// The secret was revealed on-chain, set the state of all transfers to
1256/// secret known.
1257fn handle_onchain_secret_reveal(
1258	mut chain_state: ChainState,
1259	mediator_state: Option<MediatorTransferState>,
1260	state_change: ContractReceiveSecretReveal,
1261) -> TransitionResult {
1262	let mut mediator_state = match mediator_state {
1263		Some(mediator_state) => mediator_state,
1264		None =>
1265			return Err(
1266				"ContractReceiveSecretReveal should be accompanied by a valid mediator state"
1267					.to_owned()
1268					.into(),
1269			),
1270	};
1271
1272	let mut events = vec![];
1273	if utils::is_valid_onchain_secret_reveal(&state_change, mediator_state.secrethash) {
1274		let secret = state_change.secret;
1275		// Compare against the block number at which the event was emitted.
1276		let block_number = state_change.block_number;
1277
1278		let secret_reveal = set_onchain_secret(
1279			&mut chain_state,
1280			&mut mediator_state,
1281			secret.clone(),
1282			state_change.secrethash,
1283			block_number,
1284		);
1285		let balance_proof = events_for_balance_proof(
1286			&mut chain_state,
1287			&mut mediator_state.transfers_pair,
1288			secret,
1289			state_change.secrethash,
1290		);
1291
1292		events.extend(secret_reveal);
1293		events.extend(balance_proof);
1294	}
1295
1296	Ok(MediatorTransition { new_state: Some(mediator_state), chain_state, events })
1297}
1298
1299/// Handle a `ReceiveUnlock` state change.
1300fn handle_unlock(
1301	mut chain_state: ChainState,
1302	mediator_state: Option<MediatorTransferState>,
1303	state_change: ReceiveUnlock,
1304) -> TransitionResult {
1305	let mut mediator_state = match mediator_state {
1306		Some(mediator_state) => mediator_state,
1307		None =>
1308			return Err("ReceiveUnlock should be accompanied by a valid mediator state"
1309				.to_owned()
1310				.into()),
1311	};
1312
1313	let mut events = vec![];
1314	let balance_proof_sender = state_change
1315		.balance_proof
1316		.sender
1317		.ok_or("Sender should be set".to_owned().into())?;
1318	let canonical_identifier = &state_change.balance_proof.canonical_identifier;
1319
1320	for pair in mediator_state.transfers_pair.iter_mut() {
1321		if pair.payer_transfer.balance_proof.sender == Some(balance_proof_sender) {
1322			if let Some(channel_state) = get_channel(&chain_state, canonical_identifier.clone()) {
1323				let recipient_metadata = views::get_address_metadata(
1324					balance_proof_sender,
1325					mediator_state.routes.clone(),
1326				);
1327				let mut channel_state = channel_state.clone();
1328
1329				match channel::handle_unlock(
1330					&mut channel_state,
1331					state_change.clone(),
1332					recipient_metadata,
1333				) {
1334					Ok(handle_unlock_events) => {
1335						let _ = update_channel(&mut chain_state, channel_state);
1336
1337						events.push(handle_unlock_events);
1338
1339						events.push(
1340							UnlockClaimSuccess {
1341								identifier: pair.payee_transfer.payment_identifier,
1342								secrethash: pair.payee_transfer.lock.secrethash,
1343							}
1344							.into(),
1345						);
1346
1347						pair.payer_state = PayerState::BalanceProof;
1348					},
1349					Err((_, event)) => {
1350						events.push(event);
1351					},
1352				}
1353			}
1354		}
1355	}
1356
1357	Ok(MediatorTransition { new_state: Some(mediator_state), chain_state, events })
1358}
1359
1360/// Handle `ReceiveLockExpired` state change.
1361fn handle_lock_expired(
1362	mut chain_state: ChainState,
1363	mediator_state: Option<MediatorTransferState>,
1364	state_change: ReceiveLockExpired,
1365) -> TransitionResult {
1366	let mut mediator_state = match mediator_state {
1367		Some(mediator_state) => mediator_state,
1368		None =>
1369			return Err("ReceiveLockExpired should be accompanied by a valid mediator state"
1370				.to_owned()
1371				.into()),
1372	};
1373
1374	let mut events = vec![];
1375
1376	for transfer_pair in mediator_state.transfers_pair.iter_mut() {
1377		let balance_proof = &transfer_pair.payer_transfer.balance_proof;
1378		let mut channel_state =
1379			match get_channel(&chain_state, balance_proof.canonical_identifier.clone()) {
1380				Some(channel) => channel.clone(),
1381				None =>
1382					return Ok(MediatorTransition {
1383						new_state: Some(mediator_state),
1384						chain_state,
1385						events: vec![],
1386					}),
1387			};
1388
1389		let recipient_address = channel_state.partner_state.address;
1390		let recipient_metadata =
1391			views::get_address_metadata(recipient_address, mediator_state.routes.clone());
1392		let result = channel::handle_receive_lock_expired(
1393			&mut channel_state,
1394			state_change.clone(),
1395			chain_state.block_number,
1396			recipient_metadata,
1397		)?;
1398		events.extend(result.events);
1399		if let Some(channel_state) = result.new_state {
1400			if channel::views::get_lock(&channel_state.partner_state, mediator_state.secrethash)
1401				.is_some()
1402			{
1403				transfer_pair.payer_state = PayerState::Expired;
1404			}
1405			update_channel(&mut chain_state, channel_state).map_err(Into::into)?;
1406		}
1407	}
1408
1409	if let Some(ref waiting_transfer) = mediator_state.waiting_transfer {
1410		if let Some(waiting_channel) = get_channel(
1411			&chain_state,
1412			waiting_transfer.transfer.balance_proof.canonical_identifier.clone(),
1413		) {
1414			let mut waiting_channel = waiting_channel.clone();
1415			let recipient_address = waiting_channel.partner_state.address;
1416			let recipient_metadata =
1417				views::get_address_metadata(recipient_address, mediator_state.routes.clone());
1418			let result = channel::handle_receive_lock_expired(
1419				&mut waiting_channel,
1420				state_change,
1421				chain_state.block_number,
1422				recipient_metadata,
1423			)?;
1424			if let Some(waiting_channel_state) = result.new_state {
1425				update_channel(&mut chain_state, waiting_channel_state).map_err(Into::into)?;
1426			}
1427			events.extend(result.events);
1428		}
1429	}
1430
1431	Ok(MediatorTransition { new_state: Some(mediator_state), chain_state, events })
1432}
1433
1434/// Clear the mediator task if all the locks have been finalized.
1435///
1436/// A lock is considered finalized if it has been removed from the pending locks
1437/// offchain, either because the transfer was unlocked or expired, or because the
1438/// channel was settled on chain and therefore the channel is removed.
1439pub fn clear_if_finalized(transition: MediatorTransition) -> MediatorTransition {
1440	let new_state = match transition.new_state {
1441		Some(ref new_state) => new_state,
1442		None => return transition,
1443	};
1444
1445	let secrethash = new_state.secrethash;
1446	for pair in &new_state.transfers_pair {
1447		if let Some(payer_channel) = get_channel(
1448			&transition.chain_state,
1449			pair.payer_transfer.balance_proof.canonical_identifier.clone(),
1450		) {
1451			if channel::validators::is_lock_pending(&payer_channel.partner_state, secrethash) {
1452				return transition
1453			}
1454		}
1455
1456		if let Some(payee_channel) = get_channel(
1457			&transition.chain_state,
1458			pair.payee_transfer.balance_proof.canonical_identifier.clone(),
1459		) {
1460			if channel::validators::is_lock_pending(&payee_channel.our_state, secrethash) {
1461				return transition
1462			}
1463		}
1464
1465		if let Some(waiting_transfer_state) = &new_state.waiting_transfer {
1466			let waiting_transfer = &waiting_transfer_state.transfer;
1467			let waiting_channel_identifier =
1468				waiting_transfer.balance_proof.canonical_identifier.clone();
1469			if let Some(waiting_channel) = views::get_channel_by_canonical_identifier(
1470				&transition.chain_state,
1471				waiting_channel_identifier,
1472			) {
1473				if channel::validators::is_lock_pending(&waiting_channel.partner_state, secrethash)
1474				{
1475					return transition
1476				}
1477			}
1478		}
1479	}
1480
1481	MediatorTransition {
1482		new_state: None,
1483		chain_state: transition.chain_state,
1484		events: transition.events,
1485	}
1486}
1487
1488/// Check invariants that must hold.
1489fn sanity_check(transition: MediatorTransition) -> TransitionResult {
1490	let mediator_state = match transition.new_state {
1491		Some(ref state) => state,
1492		None => return Ok(transition),
1493	};
1494
1495	if mediator_state
1496		.transfers_pair
1497		.iter()
1498		.any(|pair| PAYEE_STATE_TRANSFER_PAID.contains(&pair.payee_state)) &&
1499		mediator_state.secret.is_none()
1500	{
1501		return Err("Mediator state must have secret".to_owned().into())
1502	}
1503	if mediator_state
1504		.transfers_pair
1505		.iter()
1506		.any(|pair| PAYER_STATE_TRANSFER_PAID.contains(&pair.payer_state)) &&
1507		mediator_state.secret.is_none()
1508	{
1509		return Err("Mediator state must have secret".to_owned().into())
1510	}
1511
1512	if !mediator_state.transfers_pair.is_empty() {
1513		let first_pair = &mediator_state.transfers_pair[0];
1514		if mediator_state.secrethash != first_pair.payer_transfer.lock.secrethash {
1515			return Err("Secret hash mismatch".to_owned().into())
1516		}
1517	}
1518
1519	for pair in &mediator_state.transfers_pair {
1520		if !is_send_transfer_almost_equal(&pair.payee_transfer, &pair.payer_transfer) {
1521			return Err("Payee and payer transfers are too different".to_owned().into())
1522		}
1523	}
1524
1525	if mediator_state.transfers_pair.len() <= 2 {
1526		return Ok(transition)
1527	}
1528
1529	let exclude_last = mediator_state.transfers_pair.split_last().expect("Checked above").1;
1530	let exclude_first = mediator_state.transfers_pair.split_first().expect("Checked above").1;
1531	for (original, refund) in iter::zip(exclude_last, exclude_first) {
1532		if Some(original.payee_address) != refund.payer_transfer.balance_proof.sender {
1533			return Err("Payee/payer address mismatch".to_owned().into())
1534		}
1535
1536		let transfer_sent = &original.payee_transfer;
1537		let transfer_received = &refund.payer_transfer;
1538
1539		if !is_send_transfer_almost_equal(transfer_sent, transfer_received) {
1540			return Err("Payee and payer transfers are too different (refund)".to_owned().into())
1541		}
1542	}
1543
1544	if let Some(ref waiting_transfer) = mediator_state.waiting_transfer {
1545		let last_transfer_pair = mediator_state
1546			.transfers_pair
1547			.last()
1548			.ok_or("No transfer pairs found".to_owned().into())?;
1549
1550		let transfer_sent = &last_transfer_pair.payee_transfer;
1551		let transfer_received = &waiting_transfer.transfer;
1552
1553		if !is_send_transfer_almost_equal(transfer_sent, transfer_received) {
1554			return Err("Payee and payer transfers are too different (waiting transfer)"
1555				.to_owned()
1556				.into())
1557		}
1558	}
1559
1560	Ok(transition)
1561}
1562
1563/// Update mediator state based on the provided `state_change`.
1564pub fn state_transition(
1565	chain_state: ChainState,
1566	mediator_state: Option<MediatorTransferState>,
1567	state_change: StateChange,
1568) -> TransitionResult {
1569	let transition_result = match state_change {
1570		StateChange::Block(inner) => handle_block(chain_state, mediator_state, inner),
1571		StateChange::ActionInitMediator(inner) => handle_init(chain_state, inner),
1572		StateChange::ReceiveTransferRefund(inner) =>
1573			handle_refund_transfer(chain_state, mediator_state, inner),
1574		StateChange::ReceiveSecretReveal(inner) =>
1575			handle_offchain_secret_reveal(chain_state, mediator_state, inner),
1576		StateChange::ContractReceiveSecretReveal(inner) =>
1577			handle_onchain_secret_reveal(chain_state, mediator_state, inner),
1578		StateChange::ReceiveUnlock(inner) => handle_unlock(chain_state, mediator_state, inner),
1579		StateChange::ReceiveLockExpired(inner) =>
1580			handle_lock_expired(chain_state, mediator_state, inner),
1581		_ =>
1582			return Ok(MediatorTransition { new_state: mediator_state, chain_state, events: vec![] }),
1583	}?;
1584
1585	let transition_result = sanity_check(transition_result)?;
1586	Ok(clear_if_finalized(transition_result))
1587}