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
#![cfg(test)]
18

            
19
use {
20
    crate::{tests::common::*, AuthorNoting, RewardsPortion},
21
    cumulus_primitives_core::ParaId,
22
    parity_scale_codec::Encode,
23
    sp_consensus_aura::AURA_ENGINE_ID,
24
    sp_runtime::{generic::DigestItem, traits::BlakeTwo256},
25
    sp_std::vec,
26
    test_relay_sproof_builder::{HeaderAs, ParaHeaderSproofBuilder, ParaHeaderSproofBuilderItem},
27
    tp_traits::ContainerChainBlockInfo,
28
};
29

            
30
#[test]
31
1
fn test_reward_to_invulnerable() {
32
1
    ExtBuilder::default()
33
1
        .with_balances(vec![
34
1
            // Alice gets 10k extra tokens for her mapping deposit
35
1
            (AccountId::from(ALICE), 210_000 * UNIT),
36
1
            (AccountId::from(BOB), 100_000 * UNIT),
37
1
            (AccountId::from(CHARLIE), 100_000 * UNIT),
38
1
            (AccountId::from(DAVE), 100_000 * UNIT),
39
1
        ])
40
1
        .with_collators(vec![
41
1
            (AccountId::from(ALICE), 210 * UNIT),
42
1
            (AccountId::from(BOB), 100 * UNIT),
43
1
            (AccountId::from(CHARLIE), 100 * UNIT),
44
1
        ])
45
1
        .with_empty_parachains(vec![1001, 1002])
46
1
        .build()
47
1
        .execute_with(|| {
48
1
            // Let's get the inflation of the block.
49
1
            let summary = run_block();
50
1

            
51
1
            // Calculate Bob's rewards.
52
1
            let all_rewards = RewardsPortion::get() * summary.inflation;
53
1
            let bob_rewards = all_rewards / 2;
54
1

            
55
1
            let mut sproof = ParaHeaderSproofBuilder::default();
56
1
            let slot: u64 = 5;
57
1
            let other_para: ParaId = 1001u32.into();
58
1

            
59
1
            // In starlight there is no orchestrator chain, so instead of Charlie and Dave
60
1
            // we assign Alice and Bob.
61
1
            let assignment = TanssiCollatorAssignment::collator_container_chain();
62
1
            assert_eq!(
63
1
                assignment.container_chains[&1001u32.into()],
64
1
                vec![ALICE.into(), BOB.into()]
65
1
            );
66

            
67
            // Build the proof needed to call AuthorNoting's inherent.
68
1
            let s = ParaHeaderSproofBuilderItem {
69
1
                para_id: other_para,
70
1
                author_id: HeaderAs::NonEncoded(sp_runtime::generic::Header::<u32, BlakeTwo256> {
71
1
                    parent_hash: Default::default(),
72
1
                    number: 1,
73
1
                    state_root: Default::default(),
74
1
                    extrinsics_root: Default::default(),
75
1
                    digest: sp_runtime::generic::Digest {
76
1
                        logs: vec![DigestItem::PreRuntime(AURA_ENGINE_ID, slot.encode())],
77
1
                    },
78
1
                }),
79
1
            };
80
1
            sproof.items.push(s);
81
1

            
82
1
            let account: AccountId = BOB.into();
83
1
            let balance_before = System::account(account.clone()).data.free;
84
1

            
85
1
            // We need to set the AuthorNoting's inherent for it to also run
86
1
            // InflationRewards::on_container_authors_noted and reward the collator.
87
1
            set_author_noting_inherent_data(sproof);
88
1

            
89
1
            assert_eq!(
90
1
                AuthorNoting::latest_author(other_para),
91
1
                Some(ContainerChainBlockInfo {
92
1
                    block_number: 1,
93
1
                    author: AccountId::from(BOB),
94
1
                    latest_slot_number: 2.into(),
95
1
                })
96
1
            );
97

            
98
1
            let balance_after = System::account(account).data.free;
99
1

            
100
1
            assert_eq!(
101
1
                bob_rewards,
102
1
                balance_after - balance_before,
103
                "bob should get the correct reward portion"
104
            );
105
1
        });
106
1
}