raiden_state_machine/
views.rs

1#![warn(clippy::missing_docs_in_private_items)]
2
3use std::{
4	cmp::max,
5	collections::HashMap,
6};
7
8use raiden_primitives::types::{
9	Address,
10	AddressMetadata,
11	CanonicalIdentifier,
12	TokenAddress,
13	TokenAmount,
14	TokenNetworkAddress,
15	TokenNetworkRegistryAddress,
16	U256,
17};
18
19use crate::{
20	types::{
21		ChainState,
22		ChannelEndState,
23		ChannelState,
24		ChannelStatus,
25		RouteState,
26		TokenNetworkRegistryState,
27		TokenNetworkState,
28	},
29	views,
30};
31
32/// Returns token network by address if found
33pub fn get_token_network<'a>(
34	chain_state: &'a ChainState,
35	token_network_address: &'a Address,
36) -> Option<&'a TokenNetworkState> {
37	let mut token_network: Option<&TokenNetworkState> = None;
38
39	let token_network_registries = &chain_state.identifiers_to_tokennetworkregistries;
40	for token_network_registry in token_network_registries.values() {
41		token_network = token_network_registry
42			.tokennetworkaddresses_to_tokennetworks
43			.get(token_network_address);
44	}
45	token_network
46}
47
48/// Returns token network registry by token network address if found.
49pub fn get_token_network_registry_by_token_network_address(
50	chain_state: &ChainState,
51	token_network_address: TokenNetworkAddress,
52) -> Option<&TokenNetworkRegistryState> {
53	let token_network_registries = &chain_state.identifiers_to_tokennetworkregistries;
54	for token_network_registry in token_network_registries.values() {
55		let token_network = token_network_registry
56			.tokennetworkaddresses_to_tokennetworks
57			.get(&token_network_address);
58		if token_network.is_some() {
59			return Some(token_network_registry)
60		}
61	}
62	None
63}
64
65/// Returns token network by address if found
66pub fn get_token_network_by_address(
67	chain_state: &ChainState,
68	token_network_address: TokenNetworkAddress,
69) -> Option<&TokenNetworkState> {
70	let token_network_registries = &chain_state.identifiers_to_tokennetworkregistries;
71	token_network_registries
72		.values()
73		.flat_map(|tnr| tnr.tokennetworkaddresses_to_tokennetworks.values())
74		.find(|tn| tn.address == token_network_address)
75}
76
77/// Returns token network by token address if found.
78pub fn get_token_network_by_token_address(
79	chain_state: &ChainState,
80	registry_address: Address,
81	token_address: TokenAddress,
82) -> Option<&TokenNetworkState> {
83	let token_network_registry =
84		match chain_state.identifiers_to_tokennetworkregistries.get(&registry_address) {
85			Some(tnr) => tnr,
86			None => return None,
87		};
88
89	token_network_registry
90		.tokennetworkaddresses_to_tokennetworks
91		.values()
92		.find(|tn| tn.token_address == token_address)
93}
94
95/// Returns all channel states.
96pub fn get_channels(chain_state: &ChainState) -> Vec<ChannelState> {
97	let mut channels = vec![];
98
99	for token_network_registry in chain_state.identifiers_to_tokennetworkregistries.values() {
100		for token_network in token_network_registry.tokennetworkaddresses_to_tokennetworks.values()
101		{
102			channels.extend(token_network.channelidentifiers_to_channels.values().cloned());
103		}
104	}
105
106	channels
107}
108
109/// Returns channel state by canonical identifier if found.
110pub fn get_channel_by_canonical_identifier(
111	chain_state: &ChainState,
112	canonical_identifier: CanonicalIdentifier,
113) -> Option<&ChannelState> {
114	let token_network =
115		get_token_network_by_address(chain_state, canonical_identifier.token_network_address);
116	if let Some(token_network) = token_network {
117		return token_network
118			.channelidentifiers_to_channels
119			.get(&canonical_identifier.channel_identifier)
120	}
121	None
122}
123
124// Returns channel by token network address and partner address if found.
125pub fn get_channel_by_token_network_and_partner(
126	chain_state: &ChainState,
127	token_network_address: TokenNetworkAddress,
128	partner_address: Address,
129) -> Option<&ChannelState> {
130	let token_network = get_token_network_by_address(chain_state, token_network_address);
131	if let Some(token_network) = token_network {
132		return token_network
133			.channelidentifiers_to_channels
134			.values()
135			.find(|channel| channel.partner_state.address == partner_address)
136	}
137	None
138}
139
140/// Return channel state for registry, token and partner addresses.
141pub fn get_channel_state_for(
142	chain_state: &ChainState,
143	registry_address: Address,
144	token_address: TokenAddress,
145	partner_address: Address,
146) -> Option<&ChannelState> {
147	match get_token_network_by_token_address(chain_state, registry_address, token_address) {
148		Some(token_network) => token_network
149			.channelidentifiers_to_channels
150			.values()
151			.find(|c| c.partner_state.address == partner_address),
152		_ => None,
153	}
154}
155
156/// Return the total distributable amount of a channel state.
157pub fn channel_distributable(sender: &ChannelEndState, receiver: &ChannelEndState) -> TokenAmount {
158	let (_, _, transferred_amount, locked_amount) = sender.get_current_balanceproof();
159	let distributable = channel_balance(sender, receiver) - sender.locked_amount();
160	let overflow_limit = TokenAmount::MAX - transferred_amount - locked_amount;
161	TokenAmount::min(overflow_limit, distributable)
162}
163
164/// Returns the total balance of the sender's state of a channel.
165pub fn channel_balance(sender: &ChannelEndState, receiver: &ChannelEndState) -> U256 {
166	let mut sender_transferred_amount = U256::zero();
167	let mut receiver_transferred_amount = U256::zero();
168
169	if let Some(balance_proof) = &sender.balance_proof {
170		sender_transferred_amount = balance_proof.transferred_amount;
171	}
172	if let Some(balance_proof) = &receiver.balance_proof {
173		receiver_transferred_amount = balance_proof.transferred_amount;
174	}
175
176	sender.contract_balance + receiver_transferred_amount -
177		max(sender.offchain_total_withdraw(), sender.onchain_total_withdraw) -
178		sender_transferred_amount
179}
180
181/// Returns known token identifiers.
182pub fn get_token_identifiers(chain_state: &ChainState, registry_address: Address) -> Vec<Address> {
183	match chain_state.identifiers_to_tokennetworkregistries.get(&registry_address) {
184		Some(registry) =>
185			registry.tokenaddresses_to_tokennetworkaddresses.keys().cloned().collect(),
186		None => vec![],
187	}
188}
189
190/// Returns channel states by filter function.
191fn get_channelstate_filter(
192	chain_state: &ChainState,
193	token_network_registry_address: TokenNetworkRegistryAddress,
194	token_address: TokenAddress,
195	filter_fn: fn(&ChannelState) -> bool,
196) -> Vec<ChannelState> {
197	let token_network = match views::get_token_network_by_token_address(
198		chain_state,
199		token_network_registry_address,
200		token_address,
201	) {
202		Some(token_network) => token_network,
203		None => return vec![],
204	};
205
206	let mut result = vec![];
207
208	for channel_state in token_network.channelidentifiers_to_channels.values() {
209		if filter_fn(channel_state) {
210			result.push(channel_state.clone())
211		}
212	}
213
214	result
215}
216
217/// Returns open channel states.
218pub fn get_channelstate_open(
219	chain_state: &ChainState,
220	registry_address: Address,
221	token_address: TokenAddress,
222) -> Vec<ChannelState> {
223	get_channelstate_filter(chain_state, registry_address, token_address, |channel_state| {
224		channel_state.status() == ChannelStatus::Opened
225	})
226}
227
228/// Returns closing channel states.
229pub fn get_channelstate_closing(
230	chain_state: &ChainState,
231	registry_address: Address,
232	token_address: TokenAddress,
233) -> Vec<ChannelState> {
234	get_channelstate_filter(chain_state, registry_address, token_address, |channel_state| {
235		channel_state.status() == ChannelStatus::Closing
236	})
237}
238
239/// Returns closed channel states.
240pub fn get_channelstate_closed(
241	chain_state: &ChainState,
242	registry_address: Address,
243	token_address: TokenAddress,
244) -> Vec<ChannelState> {
245	get_channelstate_filter(chain_state, registry_address, token_address, |channel_state| {
246		channel_state.status() == ChannelStatus::Closed
247	})
248}
249
250/// Returns settling channel states.
251pub fn get_channelstate_settling(
252	chain_state: &ChainState,
253	registry_address: Address,
254	token_address: TokenAddress,
255) -> Vec<ChannelState> {
256	get_channelstate_filter(chain_state, registry_address, token_address, |channel_state| {
257		channel_state.status() == ChannelStatus::Settling
258	})
259}
260
261/// Returns settled channel states.
262pub fn get_channelstate_settled(
263	chain_state: &ChainState,
264	registry_address: Address,
265	token_address: TokenAddress,
266) -> Vec<ChannelState> {
267	get_channelstate_filter(chain_state, registry_address, token_address, |channel_state| {
268		channel_state.status() == ChannelStatus::Settled
269	})
270}
271
272/// Returns a map of (token network, partner addresses) to channels
273pub fn get_addresses_to_channels(
274	chain_state: &ChainState,
275) -> HashMap<(TokenNetworkAddress, Address), &ChannelState> {
276	let mut channels = HashMap::new();
277
278	for token_network_registry in chain_state.identifiers_to_tokennetworkregistries.values() {
279		for token_network in token_network_registry.tokennetworkaddresses_to_tokennetworks.values()
280		{
281			for channel in token_network.channelidentifiers_to_channels.values() {
282				channels.insert((token_network.address, channel.partner_state.address), channel);
283			}
284		}
285	}
286
287	channels
288}
289
290/// Filters channels by partner address
291pub fn filter_channels_by_partner_address(
292	chain_state: &ChainState,
293	registry_address: TokenNetworkAddress,
294	token_address: TokenAddress,
295	partner_addresses: Vec<Address>,
296) -> Vec<&ChannelState> {
297	let token_network =
298		match get_token_network_by_token_address(chain_state, registry_address, token_address) {
299			Some(token_network) => token_network,
300			None => return vec![],
301		};
302
303	let mut channels = vec![];
304	for partner in partner_addresses {
305		if let Some(channels_identifiers) =
306			token_network.partneraddresses_to_channelidentifiers.get(&partner)
307		{
308			for channel_id in channels_identifiers {
309				if let Some(channel_state) =
310					token_network.channelidentifiers_to_channels.get(channel_id)
311				{
312					if channel_state.status() != ChannelStatus::Unusable {
313						channels.push(channel_state);
314					}
315				}
316			}
317		}
318	}
319
320	channels
321}
322
323/// Returns address metadata.
324pub fn get_address_metadata(
325	recipient_address: Address,
326	route_states: Vec<RouteState>,
327) -> Option<AddressMetadata> {
328	for route_state in route_states {
329		match route_state.address_to_metadata.get(&recipient_address) {
330			Some(metadata) => return Some(metadata.clone()),
331			None => continue,
332		};
333	}
334
335	None
336}