1#![warn(clippy::missing_docs_in_private_items)]
2
3use raiden_primitives::types::{
4 BlockNumber,
5 CanonicalIdentifier,
6 SecretHash,
7 TokenNetworkAddress,
8 H256,
9 U64,
10};
11
12use super::{
13 initiator_manager,
14 mediator,
15 target,
16};
17use crate::{
18 errors::StateTransitionError,
19 machine::{
20 channel::{
21 self,
22 validators,
23 },
24 mediator::get_channel,
25 token_network,
26 },
27 types::{
28 ActionCancelPayment,
29 ActionInitChain,
30 ActionInitInitiator,
31 ActionInitMediator,
32 ActionInitTarget,
33 ActionTransferReroute,
34 Block,
35 ChainState,
36 ContractReceiveChannelClosed,
37 ContractReceiveTokenNetworkCreated,
38 ContractReceiveTokenNetworkRegistry,
39 ContractSendEvent,
40 Event,
41 InitiatorTask,
42 MediatorTask,
43 ReceiveDelivered,
44 ReceiveLockExpired,
45 ReceiveProcessed,
46 ReceiveSecretRequest,
47 ReceiveSecretReveal,
48 ReceiveTransferCancelRoute,
49 ReceiveTransferRefund,
50 ReceiveUnlock,
51 ReceiveWithdrawConfirmation,
52 ReceiveWithdrawExpired,
53 ReceiveWithdrawRequest,
54 StateChange,
55 TargetTask,
56 TokenNetworkState,
57 TransferRole,
58 TransferTask,
59 UpdateServicesAddresses,
60 UpdatedServicesAddresses,
61 },
62 views,
63};
64
65type TransitionResult = std::result::Result<ChainTransition, StateTransitionError>;
67
68#[derive(Debug)]
70pub struct ChainTransition {
71 pub new_state: ChainState,
72 pub events: Vec<Event>,
73}
74
75fn subdispatch_by_canonical_id(
77 chain_state: &mut ChainState,
78 state_change: StateChange,
79 canonical_identifier: CanonicalIdentifier,
80) -> TransitionResult {
81 let token_network_registries = &mut chain_state.identifiers_to_tokennetworkregistries;
82 let token_network = match token_network_registries
83 .values_mut()
84 .flat_map(|tnr| tnr.tokennetworkaddresses_to_tokennetworks.values_mut())
85 .find(|tn| tn.address == canonical_identifier.token_network_address)
86 {
87 Some(tn) => tn,
88 None => return Ok(ChainTransition { new_state: chain_state.clone(), events: vec![] }),
89 };
90
91 let transition = token_network::state_transition(
92 token_network.clone(),
93 state_change,
94 chain_state.block_number,
95 chain_state.block_hash,
96 &mut chain_state.pseudo_random_number_generator,
97 )?;
98
99 *token_network = transition.new_state;
100 let events = transition.events;
101
102 Ok(ChainTransition { new_state: chain_state.clone(), events })
103}
104
105fn subdispatch_to_all_channels(
107 mut chain_state: ChainState,
108 state_change: StateChange,
109 block_number: U64,
110 block_hash: H256,
111) -> TransitionResult {
112 let mut events = vec![];
113
114 for (_, token_network_registry) in chain_state.identifiers_to_tokennetworkregistries.iter_mut()
115 {
116 for (_, token_network) in
117 token_network_registry.tokennetworkaddresses_to_tokennetworks.iter_mut()
118 {
119 for (_, channel_state) in token_network.channelidentifiers_to_channels.iter_mut() {
120 let result = channel::state_transition(
121 channel_state.clone(),
122 state_change.clone(),
123 block_number,
124 block_hash,
125 &mut chain_state.pseudo_random_number_generator,
126 )?;
127
128 if let Some(new_state) = result.new_state {
129 *channel_state = new_state;
130 }
131 events.extend(result.events);
132 }
133 }
134 }
135
136 Ok(ChainTransition { new_state: chain_state, events })
137}
138
139fn subdispatch_to_payment_task(
141 mut chain_state: ChainState,
142 state_change: StateChange,
143 secrethash: SecretHash,
144) -> TransitionResult {
145 let mut events = vec![];
146
147 if let Some(sub_task) =
148 chain_state.payment_mapping.secrethashes_to_task.get(&secrethash).cloned()
149 {
150 match sub_task {
151 TransferTask::Initiator(mut initiator) => {
152 let sub_iteration = initiator_manager::state_transition(
153 chain_state,
154 Some(initiator.manager_state.clone()),
155 state_change,
156 )?;
157 chain_state = sub_iteration.chain_state;
158 if let Some(new_state) = sub_iteration.new_state {
159 initiator.manager_state = new_state;
160 chain_state
161 .payment_mapping
162 .secrethashes_to_task
163 .insert(secrethash, TransferTask::Initiator(initiator));
164 } else {
165 chain_state.payment_mapping.secrethashes_to_task.remove(&secrethash);
166 }
167 events.extend(sub_iteration.events);
168 },
169 TransferTask::Mediator(mut mediator) => {
170 let sub_iteration = mediator::state_transition(
171 chain_state,
172 Some(mediator.mediator_state.clone()),
173 state_change,
174 )?;
175 chain_state = sub_iteration.chain_state;
176 if let Some(new_state) = sub_iteration.new_state {
177 mediator.mediator_state = new_state;
178 chain_state
179 .payment_mapping
180 .secrethashes_to_task
181 .insert(secrethash, TransferTask::Mediator(mediator));
182 } else {
183 chain_state.payment_mapping.secrethashes_to_task.remove(&secrethash);
184 }
185 events.extend(sub_iteration.events);
186 },
187 TransferTask::Target(mut target) => {
188 let sub_iteration =
189 target::state_transition(chain_state, Some(target.target_state), state_change)?;
190 chain_state = sub_iteration.chain_state;
191 if let Some(new_state) = sub_iteration.new_state {
192 target.target_state = new_state;
193 chain_state
194 .payment_mapping
195 .secrethashes_to_task
196 .insert(secrethash, TransferTask::Target(target));
197 } else {
198 chain_state.payment_mapping.secrethashes_to_task.remove(&secrethash);
199 }
200 events.extend(sub_iteration.events);
201 },
202 }
203 }
204
205 Ok(ChainTransition { new_state: chain_state, events })
206}
207
208fn subdispatch_to_all_lockedtransfers(
210 mut chain_state: ChainState,
211 state_change: StateChange,
212) -> TransitionResult {
213 let mut events = vec![];
214
215 let payment_mapping = chain_state.payment_mapping.clone();
216 for secrethash in payment_mapping.secrethashes_to_task.keys() {
217 let result =
218 subdispatch_to_payment_task(chain_state.clone(), state_change.clone(), *secrethash)?;
219 chain_state = result.new_state;
220 events.extend(result.events);
221 }
222
223 Ok(ChainTransition { new_state: chain_state, events })
224}
225
226fn subdispatch_initiator_task(
228 chain_state: ChainState,
229 state_change: ActionInitInitiator,
230) -> TransitionResult {
231 let token_network_state = match views::get_token_network_by_address(
232 &chain_state,
233 state_change.transfer.token_network_address,
234 ) {
235 Some(tn) => tn.clone(),
236 None => return Ok(ChainTransition { new_state: chain_state, events: vec![] }),
237 };
238
239 let manager_state = match chain_state
240 .payment_mapping
241 .secrethashes_to_task
242 .get(&state_change.transfer.secrethash)
243 {
244 Some(sub_task) => {
245 let initiator = match sub_task {
246 TransferTask::Initiator(initiator)
247 if token_network_state.address == initiator.token_network_address =>
248 initiator,
249 _ => return Ok(ChainTransition { new_state: chain_state, events: vec![] }),
250 };
251 Some(initiator.manager_state.clone())
252 },
253 None => None,
254 };
255
256 if manager_state.is_some() {
257 return Ok(ChainTransition { new_state: chain_state, events: vec![] })
258 }
259
260 let initiator_state = initiator_manager::state_transition(
261 chain_state,
262 manager_state,
263 state_change.clone().into(),
264 )?;
265
266 let mut chain_state = initiator_state.chain_state;
267 match initiator_state.new_state {
268 Some(initiator_state) => {
269 chain_state.payment_mapping.secrethashes_to_task.insert(
270 state_change.transfer.secrethash,
271 TransferTask::Initiator(InitiatorTask {
272 role: TransferRole::Initiator,
273 token_network_address: token_network_state.address,
274 manager_state: initiator_state,
275 }),
276 );
277 },
278 None => {
279 chain_state
280 .payment_mapping
281 .secrethashes_to_task
282 .remove(&state_change.transfer.secrethash);
283 },
284 }
285
286 Ok(ChainTransition { new_state: chain_state, events: initiator_state.events })
287}
288
289fn subdispatch_mediator_task(
291 chain_state: ChainState,
292 state_change: ActionInitMediator,
293 token_network_address: TokenNetworkAddress,
294 secrethash: SecretHash,
295) -> TransitionResult {
296 let mediator_state = match chain_state.payment_mapping.secrethashes_to_task.get(&secrethash) {
297 Some(sub_task) => match sub_task {
298 TransferTask::Mediator(mediator_task) => Some(mediator_task.mediator_state.clone()),
299 _ => return Ok(ChainTransition { new_state: chain_state, events: vec![] }),
300 },
301 None => None,
302 };
303
304 let from_transfer = state_change.from_transfer.clone();
305 let payer_channel =
306 match get_channel(&chain_state, from_transfer.balance_proof.canonical_identifier.clone()) {
307 Some(channel) => channel.clone(),
308 None => return Ok(ChainTransition { new_state: chain_state, events: vec![] }),
309 };
310 if validators::is_valid_locked_transfer(
313 &from_transfer,
314 &payer_channel,
315 &payer_channel.partner_state,
316 &payer_channel.our_state,
317 )
318 .is_err()
319 {
320 return Ok(ChainTransition { new_state: chain_state, events: vec![] })
321 }
322
323 let mut events = vec![];
324 let iteration = mediator::state_transition(chain_state, mediator_state, state_change.into())?;
325 events.extend(iteration.events);
326
327 let mut chain_state = iteration.chain_state;
328
329 if let Some(new_state) = iteration.new_state {
330 let mediator_task = MediatorTask {
331 role: TransferRole::Mediator,
332 token_network_address,
333 mediator_state: new_state,
334 };
335 chain_state
336 .payment_mapping
337 .secrethashes_to_task
338 .insert(secrethash, TransferTask::Mediator(mediator_task));
339 } else if chain_state.payment_mapping.secrethashes_to_task.contains_key(&secrethash) {
340 chain_state.payment_mapping.secrethashes_to_task.remove(&secrethash);
341 }
342
343 Ok(ChainTransition { new_state: chain_state, events })
344}
345
346fn subdispatch_target_task(
348 chain_state: ChainState,
349 state_change: ActionInitTarget,
350 token_network_address: TokenNetworkAddress,
351 secrethash: SecretHash,
352) -> TransitionResult {
353 let target_state = match chain_state.payment_mapping.secrethashes_to_task.get(&secrethash) {
354 Some(sub_task) => match sub_task {
355 TransferTask::Target(target_task) => Some(target_task.target_state.clone()),
356 _ => return Ok(ChainTransition { new_state: chain_state, events: vec![] }),
357 },
358 None => None,
359 };
360
361 let mut events = vec![];
362
363 let iteration = target::state_transition(chain_state, target_state, state_change.into())?;
364 events.extend(iteration.events);
365
366 let mut chain_state = iteration.chain_state;
367
368 if let Some(new_state) = iteration.new_state {
369 let target_task = TargetTask {
370 role: TransferRole::Target,
371 token_network_address,
372 target_state: new_state,
373 };
374 chain_state
375 .payment_mapping
376 .secrethashes_to_task
377 .insert(secrethash, TransferTask::Target(target_task));
378 } else if chain_state.payment_mapping.secrethashes_to_task.contains_key(&secrethash) {
379 chain_state.payment_mapping.secrethashes_to_task.remove(&secrethash);
380 }
381
382 Ok(ChainTransition { new_state: chain_state, events })
383}
384
385fn handle_action_init_chain(state_change: ActionInitChain) -> TransitionResult {
387 Ok(ChainTransition {
388 new_state: ChainState::new(
389 state_change.chain_id,
390 state_change.block_number,
391 state_change.block_hash,
392 state_change.our_address,
393 ),
394 events: vec![],
395 })
396}
397
398fn handle_action_init_intiator(
400 chain_state: ChainState,
401 state_change: ActionInitInitiator,
402) -> TransitionResult {
403 subdispatch_initiator_task(chain_state, state_change)
404}
405
406fn handle_action_init_mediator(
408 chain_state: ChainState,
409 state_change: ActionInitMediator,
410) -> TransitionResult {
411 let transfer = &state_change.from_transfer;
412 let secrethash = transfer.lock.secrethash;
413 let token_network_address = transfer.balance_proof.canonical_identifier.token_network_address;
414
415 subdispatch_mediator_task(chain_state, state_change, token_network_address, secrethash)
416}
417
418fn handle_action_init_target(
420 chain_state: ChainState,
421 state_change: ActionInitTarget,
422) -> TransitionResult {
423 let transfer = &state_change.transfer;
424 let secrethash = transfer.lock.secrethash;
425 let token_network_address = transfer.balance_proof.canonical_identifier.token_network_address;
426
427 subdispatch_target_task(chain_state, state_change, token_network_address, secrethash)
428}
429
430fn handle_action_transfer_reroute(
432 mut chain_state: ChainState,
433 state_change: ActionTransferReroute,
434) -> TransitionResult {
435 let new_secrethash = state_change.secrethash;
436
437 if let Some(current_payment_task) = chain_state
438 .payment_mapping
439 .secrethashes_to_task
440 .get(&state_change.transfer.lock.secrethash)
441 .cloned()
442 {
443 chain_state
444 .payment_mapping
445 .secrethashes_to_task
446 .insert(new_secrethash, current_payment_task);
447 }
448
449 subdispatch_to_payment_task(chain_state, state_change.into(), new_secrethash)
450}
451
452fn handle_action_cancel_payment(
454 chain_state: ChainState,
455 _state_change: ActionCancelPayment,
456) -> TransitionResult {
457 Ok(ChainTransition { new_state: chain_state, events: vec![] })
458}
459
460fn handle_new_block(mut chain_state: ChainState, state_change: Block) -> TransitionResult {
462 chain_state.block_number = state_change.block_number;
463 chain_state.block_hash = state_change.block_hash;
464
465 let channels_result = subdispatch_to_all_channels(
466 chain_state.clone(),
467 state_change.clone().into(),
468 chain_state.block_number,
469 chain_state.block_hash,
470 )?;
471
472 let mut events = channels_result.events;
473
474 chain_state = channels_result.new_state;
475
476 let transfers_result = subdispatch_to_all_lockedtransfers(chain_state, state_change.into())?;
477 events.extend(transfers_result.events);
478
479 chain_state = transfers_result.new_state;
480
481 Ok(ChainTransition { new_state: chain_state, events })
482}
483
484fn handle_contract_receive_token_network_registry(
486 mut chain_state: ChainState,
487 state_change: ContractReceiveTokenNetworkRegistry,
488) -> TransitionResult {
489 chain_state
490 .identifiers_to_tokennetworkregistries
491 .entry(state_change.token_network_registry.address)
492 .or_insert(state_change.token_network_registry);
493
494 Ok(ChainTransition { new_state: chain_state, events: vec![] })
495}
496
497fn handle_contract_receive_token_network_created(
499 mut chain_state: ChainState,
500 state_change: ContractReceiveTokenNetworkCreated,
501) -> TransitionResult {
502 let token_network_registries = &mut chain_state.identifiers_to_tokennetworkregistries;
503 let token_network_registry =
504 match token_network_registries.get_mut(&state_change.token_network_registry_address) {
505 Some(token_network_registry) => token_network_registry,
506 None =>
507 return Err(StateTransitionError {
508 msg: format!(
509 "Token network registry {} was not found",
510 state_change.token_network_registry_address
511 ),
512 }),
513 };
514
515 token_network_registry
516 .tokennetworkaddresses_to_tokennetworks
517 .insert(state_change.token_network.address, state_change.token_network.clone());
518 token_network_registry
519 .tokenaddresses_to_tokennetworkaddresses
520 .insert(state_change.token_network.token_address, state_change.token_network.address);
521
522 Ok(ChainTransition { new_state: chain_state, events: vec![] })
523}
524
525fn handle_token_network_state_change(
527 mut chain_state: ChainState,
528 token_network_address: TokenNetworkAddress,
529 state_change: StateChange,
530 block_number: U64,
531 block_hash: H256,
532) -> TransitionResult {
533 let token_network_state = match views::get_token_network(&chain_state, &token_network_address) {
534 Some(token_network_state) => token_network_state,
535 None =>
536 return Err(StateTransitionError {
537 msg: format!("Token network {} was not found", token_network_address,),
538 }),
539 };
540
541 let transition = token_network::state_transition(
542 token_network_state.clone(),
543 state_change,
544 block_number,
545 block_hash,
546 &mut chain_state.pseudo_random_number_generator,
547 )?;
548
549 let new_state: TokenNetworkState = transition.new_state;
550 let registry_address =
551 views::get_token_network_registry_by_token_network_address(&chain_state, new_state.address)
552 .unwrap()
553 .address;
554 let registry = chain_state
555 .identifiers_to_tokennetworkregistries
556 .get_mut(®istry_address)
557 .unwrap();
558 registry
559 .tokennetworkaddresses_to_tokennetworks
560 .insert(new_state.address, new_state);
561
562 Ok(ChainTransition { new_state: chain_state, events: transition.events })
563}
564
565fn handle_contract_receive_channel_closed(
567 chain_state: ChainState,
568 state_change: ContractReceiveChannelClosed,
569 block_number: U64,
570 block_hash: H256,
571) -> TransitionResult {
572 let token_network_address = state_change.canonical_identifier.token_network_address;
573 handle_token_network_state_change(
574 chain_state,
575 token_network_address,
576 state_change.into(),
577 block_number,
578 block_hash,
579 )
580}
581
582fn handle_receive_transfer_cancel_route(
584 chain_state: ChainState,
585 state_change: ReceiveTransferCancelRoute,
586) -> TransitionResult {
587 let secrethash = state_change.transfer.lock.secrethash;
588 subdispatch_to_payment_task(chain_state, state_change.into(), secrethash)
589}
590
591fn handle_receive_secret_reveal(
593 chain_state: ChainState,
594 state_change: ReceiveSecretReveal,
595) -> TransitionResult {
596 let secrethash = state_change.secrethash;
597 subdispatch_to_payment_task(chain_state, state_change.into(), secrethash)
598}
599
600fn handle_receive_secret_request(
602 chain_state: ChainState,
603 state_change: ReceiveSecretRequest,
604) -> TransitionResult {
605 let secrethash = state_change.secrethash;
606 subdispatch_to_payment_task(chain_state, state_change.into(), secrethash)
607}
608
609fn handle_receive_lock_expired(
611 chain_state: ChainState,
612 state_change: ReceiveLockExpired,
613) -> TransitionResult {
614 let secrethash = state_change.secrethash;
615 subdispatch_to_payment_task(chain_state, state_change.into(), secrethash)
616}
617
618fn handle_receive_transfer_refund(
620 chain_state: ChainState,
621 state_change: ReceiveTransferRefund,
622) -> TransitionResult {
623 let secrethash = state_change.transfer.lock.secrethash;
624 subdispatch_to_payment_task(chain_state, state_change.into(), secrethash)
625}
626
627fn handle_receive_unlock(chain_state: ChainState, state_change: ReceiveUnlock) -> TransitionResult {
629 let secrethash = state_change.secrethash;
630 subdispatch_to_payment_task(chain_state, state_change.into(), secrethash)
631}
632
633fn handle_receive_withdraw_request(
635 mut chain_state: ChainState,
636 state_change: ReceiveWithdrawRequest,
637) -> TransitionResult {
638 let canonical_identifier = state_change.canonical_identifier.clone();
639 subdispatch_by_canonical_id(&mut chain_state, state_change.into(), canonical_identifier)
640}
641
642fn handle_receive_withdraw_confirmation(
644 mut chain_state: ChainState,
645 state_change: ReceiveWithdrawConfirmation,
646) -> TransitionResult {
647 let canonical_identifier = state_change.canonical_identifier.clone();
648 subdispatch_by_canonical_id(&mut chain_state, state_change.into(), canonical_identifier)
649}
650
651fn handle_receive_withdraw_expired(
653 mut chain_state: ChainState,
654 state_change: ReceiveWithdrawExpired,
655) -> TransitionResult {
656 let canonical_identifier = state_change.canonical_identifier.clone();
657 subdispatch_by_canonical_id(&mut chain_state, state_change.into(), canonical_identifier)
658}
659
660fn handle_receive_delivered(
662 chain_state: ChainState,
663 _state_change: ReceiveDelivered,
664) -> TransitionResult {
665 Ok(ChainTransition { new_state: chain_state, events: vec![] })
666}
667
668fn handle_receive_processed(
670 chain_state: ChainState,
671 _state_change: ReceiveProcessed,
672) -> TransitionResult {
673 Ok(ChainTransition { new_state: chain_state, events: vec![] })
674}
675
676fn handle_update_services_addresses(
678 chain_state: ChainState,
679 state_change: UpdateServicesAddresses,
680) -> TransitionResult {
681 let event = UpdatedServicesAddresses {
682 service_address: state_change.service,
683 validity: state_change.valid_till,
684 };
685 Ok(ChainTransition { new_state: chain_state, events: vec![event.into()] })
686}
687
688fn is_transaction_effect_satisfied(
718 chain_state: &ChainState,
719 transaction: &ContractSendEvent,
720 state_change: &StateChange,
721) -> bool {
722 if let StateChange::ContractReceiveUpdateTransfer(update_transfer_state_change) = state_change {
752 if let ContractSendEvent::ContractSendChannelUpdateTransfer(update_transfer_event) =
753 transaction
754 {
755 if update_transfer_state_change.canonical_identifier ==
756 update_transfer_event.balance_proof.canonical_identifier &&
757 update_transfer_state_change.nonce == update_transfer_event.balance_proof.nonce
758 {
759 return true
760 }
761 }
762 }
763
764 if let StateChange::ContractReceiveChannelClosed(channel_closed_state_change) = state_change {
765 if let ContractSendEvent::ContractSendChannelClose(channel_close_event) = transaction {
766 if channel_closed_state_change.canonical_identifier ==
767 channel_close_event.canonical_identifier
768 {
769 return true
770 }
771 }
772 }
773
774 if let StateChange::ContractReceiveChannelSettled(channel_settled_state_change) = state_change {
775 if let ContractSendEvent::ContractSendChannelSettle(channel_settle_event) = transaction {
776 if channel_settled_state_change.canonical_identifier ==
777 channel_settle_event.canonical_identifier
778 {
779 return true
780 }
781 }
782 }
783
784 if let StateChange::ContractReceiveSecretReveal(secret_reveal_state_change) = state_change {
785 if let ContractSendEvent::ContractSendSecretReveal(secret_reveal_event) = transaction {
786 if secret_reveal_state_change.secret == secret_reveal_event.secret {
787 return true
788 }
789 }
790 }
791
792 if let StateChange::ContractReceiveChannelBatchUnlock(batch_unlock_state_change) = state_change
793 {
794 if let ContractSendEvent::ContractSendChannelBatchUnlock(_) = transaction {
795 let our_address = chain_state.our_address;
796 let mut partner_address = None;
797 if batch_unlock_state_change.receiver == our_address {
798 partner_address = Some(batch_unlock_state_change.sender);
799 } else if batch_unlock_state_change.sender == our_address {
800 partner_address = Some(batch_unlock_state_change.receiver);
801 }
802
803 if let Some(partner_address) = partner_address {
804 let channel_state = views::get_channel_by_token_network_and_partner(
805 chain_state,
806 batch_unlock_state_change.canonical_identifier.token_network_address,
807 partner_address,
808 );
809 if channel_state.is_none() {
810 return true
811 }
812 }
813 }
814 }
815
816 false
817}
818
819fn is_transaction_invalidated(transaction: &ContractSendEvent, state_change: &StateChange) -> bool {
849 if let StateChange::ContractReceiveChannelSettled(channel_settled) = state_change {
858 if let ContractSendEvent::ContractSendChannelUpdateTransfer(update_transfer) = transaction {
859 if channel_settled.canonical_identifier ==
860 update_transfer.balance_proof.canonical_identifier
861 {
862 return true
863 }
864 }
865 }
866
867 if let StateChange::ContractReceiveChannelClosed(channel_closed) = state_change {
868 if let ContractSendEvent::ContractSendChannelWithdraw(channel_withdraw) = transaction {
869 if channel_closed.canonical_identifier == channel_withdraw.canonical_identifier {
870 return true
871 }
872 }
873 }
874
875 false
876}
877
878fn is_transaction_expired(transaction: &ContractSendEvent, block_number: BlockNumber) -> bool {
886 if let ContractSendEvent::ContractSendChannelUpdateTransfer(update_transfer) = transaction {
887 if update_transfer.expiration < block_number {
888 return true
889 }
890 }
891
892 if let ContractSendEvent::ContractSendSecretReveal(secret_reveal) = transaction {
893 if secret_reveal.expiration < block_number {
894 return true
895 }
896 }
897
898 false
899}
900
901fn is_transaction_pending(
903 chain_state: &ChainState,
904 transaction: &ContractSendEvent,
905 state_change: &StateChange,
906) -> bool {
907 !(is_transaction_effect_satisfied(chain_state, transaction, state_change) ||
908 is_transaction_invalidated(transaction, state_change) ||
909 is_transaction_expired(transaction, chain_state.block_number))
910}
911
912fn update_queues(iteration: &mut ChainTransition, state_change: StateChange) {
914 let chain_state = &mut iteration.new_state;
915 match state_change {
916 StateChange::ContractReceiveChannelOpened(_) |
917 StateChange::ContractReceiveChannelClosed(_) |
918 StateChange::ContractReceiveChannelSettled(_) |
919 StateChange::ContractReceiveChannelDeposit(_) |
920 StateChange::ContractReceiveChannelWithdraw(_) |
921 StateChange::ContractReceiveChannelBatchUnlock(_) |
922 StateChange::ContractReceiveSecretReveal(_) |
923 StateChange::ContractReceiveRouteNew(_) |
924 StateChange::ContractReceiveUpdateTransfer(_) => {
925 let mut pending_transactions = chain_state.pending_transactions.clone();
926 pending_transactions.retain(|transaction| {
927 is_transaction_pending(chain_state, transaction, &state_change)
928 });
929 chain_state.pending_transactions = pending_transactions;
930 },
931 _ => {},
932 };
933
934 for event in &iteration.events {
935 match event {
936 Event::ContractSendChannelClose(_) |
937 Event::ContractSendChannelWithdraw(_) |
938 Event::ContractSendChannelSettle(_) |
939 Event::ContractSendChannelUpdateTransfer(_) |
940 Event::ContractSendChannelBatchUnlock(_) |
941 Event::ContractSendSecretReveal(_) => {
942 chain_state
943 .pending_transactions
944 .push(event.clone().try_into().expect("Should work"));
945 },
946 _ => {},
947 }
948 }
949}
950
951pub fn state_transition(
953 mut chain_state: ChainState,
954 state_change: StateChange,
955) -> TransitionResult {
956 let update_queues_state_change = state_change.clone();
957 let mut iteration = match state_change {
958 StateChange::ActionInitChain(inner) => handle_action_init_chain(inner),
959 StateChange::ActionInitInitiator(inner) => handle_action_init_intiator(chain_state, inner),
960 StateChange::ActionInitMediator(inner) => handle_action_init_mediator(chain_state, inner),
961 StateChange::ActionInitTarget(inner) => handle_action_init_target(chain_state, inner),
962 StateChange::ActionChannelWithdraw(ref inner) => subdispatch_by_canonical_id(
963 &mut chain_state,
964 state_change.clone(),
965 inner.canonical_identifier.clone(),
966 ),
967 StateChange::ActionChannelSetRevealTimeout(ref inner) => subdispatch_by_canonical_id(
968 &mut chain_state,
969 state_change.clone(),
970 inner.canonical_identifier.clone(),
971 ),
972 StateChange::ActionTransferReroute(inner) =>
973 handle_action_transfer_reroute(chain_state, inner),
974 StateChange::ActionCancelPayment(inner) => handle_action_cancel_payment(chain_state, inner),
975 StateChange::ActionChannelClose(ref inner) => {
976 let token_network_address = inner.canonical_identifier.token_network_address;
977 let block_number = chain_state.block_number;
978 let block_hash = chain_state.block_hash;
979 handle_token_network_state_change(
980 chain_state,
981 token_network_address,
982 state_change,
983 block_number,
984 block_hash,
985 )
986 },
987 StateChange::ActionChannelCoopSettle(ref inner) => {
988 let canonical_identifier = inner.canonical_identifier.clone();
989 subdispatch_by_canonical_id(&mut chain_state, state_change, canonical_identifier)
990 },
991 StateChange::Block(inner) => handle_new_block(chain_state, inner),
992 StateChange::ContractReceiveTokenNetworkRegistry(inner) =>
993 handle_contract_receive_token_network_registry(chain_state, inner),
994 StateChange::ContractReceiveTokenNetworkCreated(inner) =>
995 handle_contract_receive_token_network_created(chain_state, inner),
996 StateChange::ContractReceiveChannelOpened(ref inner) => {
997 let token_network_address =
998 inner.channel_state.canonical_identifier.token_network_address;
999 let block_number = chain_state.block_number;
1000 let block_hash = chain_state.block_hash;
1001 handle_token_network_state_change(
1002 chain_state,
1003 token_network_address,
1004 state_change,
1005 block_number,
1006 block_hash,
1007 )
1008 },
1009 StateChange::ContractReceiveChannelClosed(inner) => {
1010 let block_number = chain_state.block_number;
1011 let block_hash = chain_state.block_hash;
1012 handle_contract_receive_channel_closed(chain_state, inner, block_number, block_hash)
1013 },
1014 StateChange::ContractReceiveChannelSettled(ref inner) => {
1015 let block_number = chain_state.block_number;
1016 let block_hash = chain_state.block_hash;
1017 let token_network_address = inner.canonical_identifier.token_network_address;
1018 handle_token_network_state_change(
1019 chain_state.clone(),
1020 token_network_address,
1021 state_change,
1022 block_number,
1023 block_hash,
1024 )
1025 },
1026 StateChange::ContractReceiveChannelDeposit(ref inner) => {
1027 let block_number = chain_state.block_number;
1028 let block_hash = chain_state.block_hash;
1029 let token_network_address = inner.canonical_identifier.token_network_address;
1030 handle_token_network_state_change(
1031 chain_state.clone(),
1032 token_network_address,
1033 state_change,
1034 block_number,
1035 block_hash,
1036 )
1037 },
1038 StateChange::ContractReceiveChannelWithdraw(ref inner) => {
1039 let block_number = chain_state.block_number;
1040 let block_hash = chain_state.block_hash;
1041 let token_network_address = inner.canonical_identifier.token_network_address;
1042 handle_token_network_state_change(
1043 chain_state.clone(),
1044 token_network_address,
1045 state_change,
1046 block_number,
1047 block_hash,
1048 )
1049 },
1050 StateChange::ContractReceiveChannelBatchUnlock(ref inner) => {
1051 let block_number = chain_state.block_number;
1052 let block_hash = chain_state.block_hash;
1053 let token_network_address = inner.canonical_identifier.token_network_address;
1054 handle_token_network_state_change(
1055 chain_state.clone(),
1056 token_network_address,
1057 state_change,
1058 block_number,
1059 block_hash,
1060 )
1061 },
1062 StateChange::ContractReceiveUpdateTransfer(ref inner) => {
1063 let block_number = chain_state.block_number;
1064 let block_hash = chain_state.block_hash;
1065 let token_network_address = inner.canonical_identifier.token_network_address;
1066 handle_token_network_state_change(
1067 chain_state,
1068 token_network_address,
1069 state_change,
1070 block_number,
1071 block_hash,
1072 )
1073 },
1074 StateChange::ContractReceiveSecretReveal(ref inner) =>
1075 subdispatch_to_payment_task(chain_state, state_change.clone(), inner.secrethash),
1076 StateChange::ContractReceiveRouteNew(_) =>
1077 Ok(ChainTransition { new_state: chain_state, events: vec![] }),
1078 StateChange::ReceiveTransferCancelRoute(inner) =>
1079 handle_receive_transfer_cancel_route(chain_state, inner),
1080 StateChange::ReceiveSecretReveal(inner) => handle_receive_secret_reveal(chain_state, inner),
1081 StateChange::ReceiveSecretRequest(inner) =>
1082 handle_receive_secret_request(chain_state, inner),
1083 StateChange::ReceiveLockExpired(inner) => handle_receive_lock_expired(chain_state, inner),
1084 StateChange::ReceiveTransferRefund(inner) =>
1085 handle_receive_transfer_refund(chain_state, inner),
1086 StateChange::ReceiveUnlock(inner) => handle_receive_unlock(chain_state, inner),
1087 StateChange::ReceiveWithdrawRequest(inner) =>
1088 handle_receive_withdraw_request(chain_state, inner),
1089 StateChange::ReceiveWithdrawConfirmation(inner) =>
1090 handle_receive_withdraw_confirmation(chain_state, inner),
1091 StateChange::ReceiveWithdrawExpired(inner) =>
1092 handle_receive_withdraw_expired(chain_state, inner),
1093 StateChange::ReceiveDelivered(inner) => handle_receive_delivered(chain_state, inner),
1094 StateChange::ReceiveProcessed(inner) => handle_receive_processed(chain_state, inner),
1095 StateChange::UpdateServicesAddresses(inner) =>
1096 handle_update_services_addresses(chain_state, inner),
1097 }?;
1098
1099 update_queues(&mut iteration, update_queues_state_change);
1100
1101 Ok(iteration)
1102}