1
// Copyright (C) Moondance Labs Ltd.
2
// This file is part of Tanssi.
3

            
4
// Tanssi is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8

            
9
// Tanssi is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13

            
14
// You should have received a copy of the GNU General Public License
15
// along with Tanssi.  If not, see <http://www.gnu.org/licenses/>
16

            
17
use {
18
    crate::*,
19
    core::marker::PhantomData,
20
    frame_support::ensure,
21
    frame_support::traits::EnqueueMessage,
22
    snowbridge_core::{ChannelId, PRIMARY_GOVERNANCE_CHANNEL},
23
    snowbridge_outbound_queue_primitives::v2::Message as MessageV2,
24
    snowbridge_outbound_queue_primitives::SendError,
25
    sp_core::H256,
26
    sp_runtime::traits::Convert,
27
};
28

            
29
/// Alternative to [snowbridge_pallet_outbound_queue::Pallet::deliver] using a different
30
/// origin.
31
/// Snowbridge V1 implementation!
32
pub struct TanssiEthMessageSenderV1<T, GetAggregateMessageOrigin>(
33
    PhantomData<(T, GetAggregateMessageOrigin)>,
34
);
35

            
36
impl<T, GetAggregateMessageOrigin> DeliverMessage
37
    for TanssiEthMessageSenderV1<T, GetAggregateMessageOrigin>
38
where
39
    T: snowbridge_pallet_outbound_queue::Config,
40
    GetAggregateMessageOrigin:
41
        Convert<ChannelId, <T as snowbridge_pallet_outbound_queue::Config>::AggregateMessageOrigin>,
42
{
43
    type Ticket = TanssiTicketV1<T>;
44

            
45
86
    fn deliver(ticket: Self::Ticket) -> Result<sp_core::H256, SendError> {
46
86
        let origin = GetAggregateMessageOrigin::convert(ticket.channel_id);
47

            
48
86
        if ticket.channel_id != PRIMARY_GOVERNANCE_CHANNEL {
49
            ensure!(
50
                !<snowbridge_pallet_outbound_queue::Pallet<T>>::operating_mode().is_halted(),
51
                SendError::Halted
52
            );
53
86
        }
54

            
55
86
        let message = ticket.message.as_bounded_slice();
56

            
57
86
        <T as snowbridge_pallet_outbound_queue::Config>::MessageQueue::enqueue_message(
58
86
            message, origin,
59
        );
60
86
        snowbridge_pallet_outbound_queue::Pallet::<T>::deposit_event(
61
86
            snowbridge_pallet_outbound_queue::Event::MessageQueued {
62
86
                id: ticket.message_id,
63
86
            },
64
        );
65

            
66
86
        Ok(ticket.message_id)
67
86
    }
68
}
69

            
70
/// Alternative to [snowbridge_pallet_outbound_queue::Pallet::deliver] using a different
71
/// origin.
72
pub struct TanssiEthMessageSenderV2<T, GetAggregateMessageOrigin>(
73
    PhantomData<(T, GetAggregateMessageOrigin)>,
74
);
75

            
76
impl<T, GetAggregateMessageOrigin> DeliverMessage
77
    for TanssiEthMessageSenderV2<T, GetAggregateMessageOrigin>
78
where
79
    T: snowbridge_pallet_outbound_queue_v2::Config,
80
    GetAggregateMessageOrigin:
81
        Convert<H256, <T as snowbridge_pallet_outbound_queue_v2::Config>::AggregateMessageOrigin>,
82
{
83
    type Ticket = TanssiTicketV2<T>;
84

            
85
2
    fn deliver(ticket: Self::Ticket) -> Result<sp_core::H256, SendError> {
86
2
        let origin = GetAggregateMessageOrigin::convert(ticket.origin);
87

            
88
2
        let message = ticket.message.as_bounded_slice();
89
2
        <T as snowbridge_pallet_outbound_queue_v2::Config>::MessageQueue::enqueue_message(
90
2
            message, origin,
91
        );
92
2
        snowbridge_pallet_outbound_queue_v2::Pallet::<T>::deposit_event(
93
2
            snowbridge_pallet_outbound_queue_v2::Event::MessageQueued {
94
2
                message: MessageV2 {
95
2
                    origin: ticket.origin,
96
2
                    fee: ticket.fee,
97
2
                    id: ticket.id,
98
2
                    commands: vec![].try_into().unwrap(),
99
2
                },
100
2
            },
101
        );
102

            
103
2
        Ok(ticket.id)
104
2
    }
105
}
106

            
107
pub struct VersionedTanssiEthMessageSender<T, GetAggregateMessageOrigin>(
108
    PhantomData<(T, GetAggregateMessageOrigin)>,
109
);
110

            
111
impl<T, GetAggregateMessageOrigin> DeliverMessage
112
    for VersionedTanssiEthMessageSender<T, GetAggregateMessageOrigin>
113
where
114
    T: snowbridge_pallet_outbound_queue::Config + snowbridge_pallet_outbound_queue_v2::Config,
115
    GetAggregateMessageOrigin: Convert<ChannelId, <T as snowbridge_pallet_outbound_queue::Config>::AggregateMessageOrigin>
116
        + Convert<H256, <T as snowbridge_pallet_outbound_queue_v2::Config>::AggregateMessageOrigin>,
117
{
118
    type Ticket = VersionedTanssiTicket<T>;
119

            
120
2
    fn deliver(ticket: Self::Ticket) -> Result<sp_core::H256, SendError> {
121
2
        match ticket {
122
1
            VersionedTanssiTicket::V1(ticket) => {
123
1
                TanssiEthMessageSenderV1::<T, GetAggregateMessageOrigin>::deliver(ticket)
124
            }
125
1
            VersionedTanssiTicket::V2(ticket) => {
126
1
                TanssiEthMessageSenderV2::<T, GetAggregateMessageOrigin>::deliver(ticket)
127
            }
128
        }
129
2
    }
130
}