1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/*!
   Functions for bootstrapping N-ary number of connections.
*/

use core::convert::TryInto;
use core::time::Duration;
use ibc_relayer::chain::handle::ChainHandle;
use ibc_relayer::foreign_client::ForeignClient;

use crate::bootstrap::binary::connection::{bootstrap_connection, BootstrapConnectionOptions};
use crate::error::Error;
use crate::types::binary::connection::ConnectedConnection;
use crate::types::binary::foreign_client::ForeignClientPair;
use crate::types::nary::connection::{ConnectedConnections, DynamicConnectedConnections};
use crate::types::nary::foreign_client::ForeignClientPairs;
use crate::util::array::assert_same_dimension;

/**
   Bootstrap a dynamic number of connections based on the
   given foreign client NxN matrix.
*/
pub fn bootstrap_connections_dynamic<Handle: ChainHandle>(
    foreign_clients: &Vec<Vec<ForeignClient<Handle, Handle>>>,
    connection_delay: Duration,
    bootstrap_with_random_ids: bool,
) -> Result<DynamicConnectedConnections<Handle>, Error> {
    let size = foreign_clients.len();

    assert_same_dimension(size, foreign_clients)?;

    let mut connections: Vec<Vec<ConnectedConnection<Handle, Handle>>> = Vec::new();

    for (i, foreign_clients_b) in foreign_clients.iter().enumerate() {
        let mut connections_b: Vec<ConnectedConnection<Handle, Handle>> = Vec::new();

        for (j, foreign_client) in foreign_clients_b.iter().enumerate() {
            if i <= j {
                let counter_foreign_client = &foreign_clients[j][i];
                let foreign_clients =
                    ForeignClientPair::new(foreign_client.clone(), counter_foreign_client.clone());

                let bootstrap_options = BootstrapConnectionOptions::default()
                    .connection_delay(connection_delay)
                    .bootstrap_with_random_ids(bootstrap_with_random_ids);

                let connection = bootstrap_connection(&foreign_clients, bootstrap_options)?;

                connections_b.push(connection);
            } else {
                let counter_connection = &connections[j][i];
                let connection = counter_connection.clone().flip();

                connections_b.push(connection);
            }
        }

        connections.push(connections_b);
    }

    Ok(DynamicConnectedConnections::new(connections))
}

pub fn bootstrap_connections<Handle: ChainHandle, const SIZE: usize>(
    foreign_clients: ForeignClientPairs<Handle, SIZE>,
    connection_delay: Duration,
    bootstrap_with_random_ids: bool,
) -> Result<ConnectedConnections<Handle, SIZE>, Error> {
    let connections = bootstrap_connections_dynamic(
        &foreign_clients.into_nested_vec(),
        connection_delay,
        bootstrap_with_random_ids,
    )?;

    connections.try_into()
}