raiden_state_machine/machine/
token_network.rs1#![warn(clippy::missing_docs_in_private_items)]
2
3use raiden_primitives::types::{
4 H256,
5 U256,
6 U64,
7};
8
9use super::channel;
10use crate::{
11 errors::StateTransitionError,
12 types::{
13 ContractReceiveChannelOpened,
14 Event,
15 Random,
16 StateChange,
17 TokenNetworkState,
18 },
19};
20
21type TransitionResult = std::result::Result<TokenNetworkTransition, StateTransitionError>;
23
24#[derive(Debug)]
26pub struct TokenNetworkTransition {
27 pub new_state: TokenNetworkState,
28 pub events: Vec<Event>,
29}
30
31fn subdispatch_to_channel_by_id(
33 mut token_network_state: TokenNetworkState,
34 channel_identifier: U256,
35 state_change: StateChange,
36 block_number: U64,
37 block_hash: H256,
38 pseudo_random_number_generator: &mut Random,
39) -> TransitionResult {
40 let channel_state =
41 match token_network_state.channelidentifiers_to_channels.get(&channel_identifier) {
42 Some(channel_state) => channel_state.clone(),
43 None =>
44 return Ok(TokenNetworkTransition { new_state: token_network_state, events: vec![] }),
45 };
46
47 let result = channel::state_transition(
48 channel_state.clone(),
49 state_change,
50 block_number,
51 block_hash,
52 pseudo_random_number_generator,
53 )?;
54 match result.new_state {
55 Some(channel_state) => {
56 token_network_state
57 .channelidentifiers_to_channels
58 .insert(channel_identifier, channel_state);
59 },
60 None => {
61 token_network_state.channelidentifiers_to_channels.remove(&channel_identifier);
62
63 token_network_state
64 .partneraddresses_to_channelidentifiers
65 .remove(&channel_state.partner_state.address);
66 },
67 }
68
69 Ok(TokenNetworkTransition { new_state: token_network_state, events: result.events })
70}
71
72fn handle_contract_receive_channel_opened(
74 mut token_network_state: TokenNetworkState,
75 state_change: ContractReceiveChannelOpened,
76) -> TransitionResult {
77 let channel_state = state_change.channel_state;
78 let canonical_identifier = channel_state.canonical_identifier.clone();
79
80 token_network_state
81 .partneraddresses_to_channelidentifiers
82 .entry(channel_state.partner_state.address)
83 .or_insert(vec![]);
84 if let Some(entry) = token_network_state
85 .partneraddresses_to_channelidentifiers
86 .get_mut(&channel_state.partner_state.address)
87 {
88 if !entry.contains(&canonical_identifier.channel_identifier) {
89 entry.push(canonical_identifier.channel_identifier);
90 }
91 }
92
93 token_network_state
94 .channelidentifiers_to_channels
95 .entry(canonical_identifier.channel_identifier)
96 .or_insert(channel_state);
97
98 Ok(TokenNetworkTransition { new_state: token_network_state, events: vec![] })
99}
100
101pub fn state_transition(
103 token_network_state: TokenNetworkState,
104 state_change: StateChange,
105 block_number: U64,
106 block_hash: H256,
107 pseudo_random_number_generator: &mut Random,
108) -> TransitionResult {
109 match state_change {
110 StateChange::ActionChannelClose(ref inner) => {
111 let channel_identifier = inner.canonical_identifier.channel_identifier;
112 subdispatch_to_channel_by_id(
113 token_network_state,
114 channel_identifier,
115 state_change,
116 block_number,
117 block_hash,
118 pseudo_random_number_generator,
119 )
120 },
121 StateChange::ActionChannelWithdraw(ref inner) => {
122 let channel_identifier = inner.canonical_identifier.channel_identifier;
123 subdispatch_to_channel_by_id(
124 token_network_state,
125 channel_identifier,
126 state_change,
127 block_number,
128 block_hash,
129 pseudo_random_number_generator,
130 )
131 },
132 StateChange::ActionChannelCoopSettle(ref inner) => {
133 let channel_identifier = inner.canonical_identifier.channel_identifier;
134 subdispatch_to_channel_by_id(
135 token_network_state,
136 channel_identifier,
137 state_change,
138 block_number,
139 block_hash,
140 pseudo_random_number_generator,
141 )
142 },
143 StateChange::ActionChannelSetRevealTimeout(ref inner) => {
144 let channel_identifier = inner.canonical_identifier.channel_identifier;
145 subdispatch_to_channel_by_id(
146 token_network_state,
147 channel_identifier,
148 state_change,
149 block_number,
150 block_hash,
151 pseudo_random_number_generator,
152 )
153 },
154 StateChange::ContractReceiveChannelOpened(inner) =>
155 handle_contract_receive_channel_opened(token_network_state, inner),
156 StateChange::ContractReceiveChannelClosed(ref inner) => {
157 let channel_identifier = inner.canonical_identifier.channel_identifier;
158 subdispatch_to_channel_by_id(
159 token_network_state,
160 channel_identifier,
161 state_change,
162 block_number,
163 block_hash,
164 pseudo_random_number_generator,
165 )
166 },
167 StateChange::ContractReceiveChannelDeposit(ref inner) => {
168 let channel_identifier = inner.canonical_identifier.channel_identifier;
169 subdispatch_to_channel_by_id(
170 token_network_state,
171 channel_identifier,
172 state_change,
173 block_number,
174 block_hash,
175 pseudo_random_number_generator,
176 )
177 },
178 StateChange::ContractReceiveChannelWithdraw(ref inner) => {
179 let channel_identifier = inner.canonical_identifier.channel_identifier;
180 subdispatch_to_channel_by_id(
181 token_network_state,
182 channel_identifier,
183 state_change,
184 block_number,
185 block_hash,
186 pseudo_random_number_generator,
187 )
188 },
189 StateChange::ContractReceiveChannelSettled(ref inner) => {
190 let channel_identifier = inner.canonical_identifier.channel_identifier;
191 subdispatch_to_channel_by_id(
192 token_network_state,
193 channel_identifier,
194 state_change,
195 block_number,
196 block_hash,
197 pseudo_random_number_generator,
198 )
199 },
200 StateChange::ContractReceiveUpdateTransfer(ref inner) => {
201 let channel_identifier = inner.canonical_identifier.channel_identifier;
202 subdispatch_to_channel_by_id(
203 token_network_state,
204 channel_identifier,
205 state_change,
206 block_number,
207 block_hash,
208 pseudo_random_number_generator,
209 )
210 },
211 StateChange::ContractReceiveChannelBatchUnlock(ref inner) => {
212 let channel_identifier = inner.canonical_identifier.channel_identifier;
213 subdispatch_to_channel_by_id(
214 token_network_state,
215 channel_identifier,
216 state_change,
217 block_number,
218 block_hash,
219 pseudo_random_number_generator,
220 )
221 },
222 StateChange::ReceiveWithdrawRequest(ref inner) => {
223 let channel_identifier = inner.canonical_identifier.channel_identifier;
224 subdispatch_to_channel_by_id(
225 token_network_state,
226 channel_identifier,
227 state_change,
228 block_number,
229 block_hash,
230 pseudo_random_number_generator,
231 )
232 },
233 StateChange::ReceiveWithdrawConfirmation(ref inner) => {
234 let channel_identifier = inner.canonical_identifier.channel_identifier;
235 subdispatch_to_channel_by_id(
236 token_network_state,
237 channel_identifier,
238 state_change,
239 block_number,
240 block_hash,
241 pseudo_random_number_generator,
242 )
243 },
244 StateChange::ReceiveWithdrawExpired(ref inner) => {
245 let channel_identifier = inner.canonical_identifier.channel_identifier;
246 subdispatch_to_channel_by_id(
247 token_network_state,
248 channel_identifier,
249 state_change,
250 block_number,
251 block_hash,
252 pseudo_random_number_generator,
253 )
254 },
255 _ => Err(StateTransitionError { msg: String::from("Could not transition token network") }),
256 }
257}