simperby_settlement/
tests.rs1use super::*;
4use execution::*;
5use simperby_core::{verify::CommitSequenceVerifier, *};
6use std::time::Duration;
7use tokio::time::sleep;
8
9pub struct ChainInfo {
10 pub chain_name: String,
11 pub last_finalized_header: BlockHeader,
12 pub last_finalization_proof: FinalizationProof,
13 pub reserved_state: ReservedState,
14 pub validators: Vec<PrivateKey>,
18}
19
20impl ChainInfo {
21 pub fn standard_genesis(chain_name: String) -> Self {
25 let (reserved_state, validators) = test_utils::generate_standard_genesis(4);
26 Self {
27 chain_name,
28 last_finalized_header: reserved_state.genesis_info.header.clone(),
29 last_finalization_proof: reserved_state.genesis_info.genesis_proof.clone(),
30 reserved_state,
31 validators: validators
32 .into_iter()
33 .map(|(_, private_key)| private_key)
34 .collect(),
35 }
36 }
37}
38
39pub async fn scenario_1(
44 chain_info: ChainInfo,
45 initial_contract_sequence: u128,
46 token_address: HexSerializedVec,
47 temporary_receiver_address: HexSerializedVec,
48 sc: impl SettlementChain,
49 transaction_finalization_wait: Duration,
50) {
51 let mut csv = CommitSequenceVerifier::new(
53 chain_info.last_finalized_header.clone(),
54 chain_info.reserved_state.clone(),
55 )
56 .unwrap();
57
58 let initial_balance = sc
60 .get_treasury_fungible_token_balance(token_address.clone())
61 .await
62 .unwrap();
63 let initial_treasury_header = sc.get_light_client_header().await.unwrap();
64 let contract_sequence = sc.get_contract_sequence().await.unwrap();
65 let initial_temporary_receiver_balance = sc
66 .eoa_get_fungible_token_balance(temporary_receiver_address.clone(), token_address.clone())
67 .await
68 .unwrap();
69 assert_eq!(initial_treasury_header, chain_info.last_finalized_header);
70 assert_eq!(contract_sequence, initial_contract_sequence);
71
72 let mut transactions = Vec::new();
74 for i in 0..10 {
75 let tx = Transaction {
76 author: "doesn't matter".to_owned(),
77 timestamp: 0,
78 head: format!("commit {i}"),
79 body: "".to_owned(),
80 diff: Diff::None,
81 };
82 csv.apply_commit(&Commit::Transaction(tx.clone())).unwrap();
83 transactions.push(tx);
84 }
85 let execute_tx = execution::create_execution_transaction(
86 &Execution {
87 target_chain: chain_info.chain_name,
88 contract_sequence: initial_contract_sequence,
89 message: ExecutionMessage::TransferFungibleToken(TransferFungibleToken {
90 token_address: token_address.clone(),
91 amount: initial_balance,
92 receiver_address: temporary_receiver_address.clone(),
93 }),
94 },
95 "hi".to_owned(),
96 1234,
97 )
98 .unwrap();
99 csv.apply_commit(&Commit::Transaction(execute_tx.clone()))
100 .unwrap();
101 transactions.push(execute_tx.clone());
102 for i in 0..20 {
103 let tx = Transaction {
104 author: "doesn't matter".to_owned(),
105 timestamp: 0,
106 head: format!("commit {i}"),
107 body: "".to_owned(),
108 diff: Diff::None,
109 };
110 csv.apply_commit(&Commit::Transaction(tx.clone())).unwrap();
111 transactions.push(tx);
112 }
113
114 let agenda = Agenda {
116 height: 1,
117 author: chain_info.reserved_state.consensus_leader_order[0].clone(),
118 timestamp: 0,
119 transactions_hash: Agenda::calculate_transactions_hash(&transactions),
120 previous_block_hash: chain_info.last_finalized_header.to_hash256(),
121 };
122 csv.apply_commit(&Commit::Agenda(agenda.clone())).unwrap();
123 csv.apply_commit(&Commit::AgendaProof(AgendaProof {
124 height: 1,
125 agenda_hash: agenda.to_hash256(),
126 proof: chain_info
127 .validators
128 .iter()
129 .map(|private_key| TypedSignature::sign(&agenda, private_key).unwrap())
130 .collect::<Vec<_>>(),
131 timestamp: 0,
132 }))
133 .unwrap();
134 let block_header = BlockHeader {
135 author: chain_info.validators[0].public_key(),
136 prev_block_finalization_proof: chain_info.last_finalization_proof,
137 previous_hash: chain_info.last_finalized_header.to_hash256(),
138 height: 1,
139 timestamp: 0,
140 commit_merkle_root: BlockHeader::calculate_commit_merkle_root(
141 &csv.get_total_commits()[1..],
142 ),
143 repository_merkle_root: Hash256::zero(),
144 validator_set: chain_info.last_finalized_header.validator_set.clone(),
145 version: chain_info.last_finalized_header.version,
146 };
147 csv.apply_commit(&Commit::Block(block_header.clone()))
148 .unwrap();
149 let signatures = chain_info
150 .validators
151 .iter()
152 .map(|private_key| {
153 TypedSignature::sign(
154 &FinalizationSignTarget {
155 block_hash: block_header.to_hash256(),
156 round: 0,
157 },
158 private_key,
159 )
160 .unwrap()
161 })
162 .collect::<Vec<_>>();
163 let fp = FinalizationProof {
164 round: 0,
165 signatures,
166 };
167 csv.verify_last_header_finalization(&fp).unwrap();
168
169 sc.update_treasury_light_client(block_header.clone(), fp)
171 .await
172 .unwrap();
173 sleep(transaction_finalization_wait).await;
174 assert_eq!(sc.get_light_client_header().await.unwrap(), block_header);
175
176 let commits = csv.get_total_commits();
178 let merkle_tree = OneshotMerkleTree::create(
179 commits[1..=(commits.len() - 2)]
180 .iter()
181 .map(|c| c.to_hash256())
182 .collect(),
183 );
184 let merkle_proof = merkle_tree
185 .create_merkle_proof(execute_tx.to_hash256())
186 .unwrap();
187 sc.execute(execute_tx, 1, merkle_proof).await.unwrap();
188 sleep(transaction_finalization_wait).await;
189
190 assert_eq!(
192 sc.eoa_get_fungible_token_balance(
193 temporary_receiver_address.clone(),
194 token_address.clone()
195 )
196 .await
197 .unwrap(),
198 initial_temporary_receiver_balance + initial_balance
199 );
200}