1
1
use core:: fmt:: Debug ;
2
2
use core:: time:: Duration ;
3
3
4
- use basecoin_store:: avl:: get_proof_spec as basecoin_proof_spec;
5
4
use basecoin_store:: context:: ProvableStore ;
6
5
use basecoin_store:: impls:: { GrowingStore , InMemoryStore , RevertibleStore } ;
7
6
use ibc:: core:: channel:: types:: channel:: ChannelEnd ;
8
7
use ibc:: core:: channel:: types:: commitment:: PacketCommitment ;
9
8
use ibc:: core:: client:: context:: client_state:: ClientStateValidation ;
10
- use ibc:: core:: client:: context:: ClientExecutionContext ;
9
+ use ibc:: core:: client:: context:: { ClientExecutionContext , ClientValidationContext } ;
11
10
use ibc:: core:: client:: types:: Height ;
12
- use ibc:: core:: commitment_types:: specs:: ProofSpecs ;
13
11
use ibc:: core:: connection:: types:: ConnectionEnd ;
14
12
use ibc:: core:: entrypoint:: dispatch;
15
13
use ibc:: core:: handler:: types:: events:: IbcEvent ;
@@ -20,16 +18,15 @@ use ibc::core::host::types::path::{
20
18
SeqAckPath , SeqRecvPath , SeqSendPath ,
21
19
} ;
22
20
use ibc:: core:: host:: { ExecutionContext , ValidationContext } ;
23
- use ibc:: core:: router:: router:: Router ;
24
21
use ibc:: primitives:: prelude:: * ;
25
22
use ibc:: primitives:: Timestamp ;
26
- use typed_builder:: TypedBuilder ;
27
23
28
24
use super :: testapp:: ibc:: core:: types:: { LightClientState , MockIbcStore } ;
29
25
use crate :: fixtures:: core:: context:: MockContextConfig ;
30
26
use crate :: hosts:: { HostClientState , TestBlock , TestHeader , TestHost } ;
31
27
use crate :: relayer:: error:: RelayerError ;
32
28
use crate :: testapp:: ibc:: clients:: { AnyClientState , AnyConsensusState } ;
29
+ use crate :: testapp:: ibc:: core:: router:: MockRouter ;
33
30
use crate :: testapp:: ibc:: core:: types:: DEFAULT_BLOCK_TIME_SECS ;
34
31
35
32
/// A context implementing the dependencies necessary for testing any IBC module.
@@ -40,34 +37,23 @@ where
40
37
H : TestHost ,
41
38
HostClientState < H > : ClientStateValidation < MockIbcStore < S > > ,
42
39
{
40
+ /// The multi store of the context.
41
+ /// This is where the IBC store root is stored at IBC commitment prefix.
42
+ pub multi_store : S ,
43
+
43
44
/// The type of host chain underlying this mock context.
44
45
pub host : H ,
45
46
46
47
/// An object that stores all IBC related data.
47
48
pub ibc_store : MockIbcStore < S > ,
49
+
50
+ /// A router that can route messages to the appropriate IBC application.
51
+ pub ibc_router : MockRouter ,
48
52
}
49
53
50
54
pub type MockStore = RevertibleStore < GrowingStore < InMemoryStore > > ;
51
55
pub type MockContext < H > = MockGenericContext < MockStore , H > ;
52
56
53
- #[ derive( Debug , TypedBuilder ) ]
54
- pub struct MockClientConfig {
55
- #[ builder( default = Duration :: from_secs( 64000 ) ) ]
56
- pub trusting_period : Duration ,
57
- #[ builder( default = Duration :: from_millis( 3000 ) ) ]
58
- pub max_clock_drift : Duration ,
59
- #[ builder( default = Duration :: from_secs( 128_000 ) ) ]
60
- pub unbonding_period : Duration ,
61
- #[ builder( default = vec![ basecoin_proof_spec( ) ] . into( ) ) ]
62
- pub proof_specs : ProofSpecs ,
63
- }
64
-
65
- impl Default for MockClientConfig {
66
- fn default ( ) -> Self {
67
- Self :: builder ( ) . build ( )
68
- }
69
- }
70
-
71
57
/// Returns a MockContext with bare minimum initialization: no clients, no connections and no channels are
72
58
/// present, and the chain has Height(5). This should be used sparingly, mostly for testing the
73
59
/// creation of new domain objects.
94
80
& self . ibc_store
95
81
}
96
82
83
+ pub fn ibc_store_mut ( & mut self ) -> & mut MockIbcStore < S > {
84
+ & mut self . ibc_store
85
+ }
86
+
97
87
pub fn host_block ( & self , target_height : & Height ) -> Option < H :: Block > {
98
88
self . host . get_block ( target_height)
99
89
}
@@ -102,6 +92,13 @@ where
102
92
self . host . get_block ( & self . latest_height ( ) )
103
93
}
104
94
95
+ pub fn light_client_latest_height ( & self , client_id : & ClientId ) -> Height {
96
+ self . ibc_store
97
+ . client_state ( client_id)
98
+ . expect ( "client state exists" )
99
+ . latest_height ( )
100
+ }
101
+
105
102
pub fn advance_block_up_to ( mut self , target_height : Height ) -> Self {
106
103
let latest_height = self . host . latest_height ( ) ;
107
104
if target_height. revision_number ( ) != latest_height. revision_number ( ) {
@@ -118,38 +115,79 @@ where
118
115
}
119
116
120
117
pub fn generate_genesis_block ( & mut self , genesis_time : Timestamp , params : & H :: BlockParams ) {
121
- // commit store
122
- let app_hash = self . ibc_store . commit ( ) . expect ( "no error" ) ;
118
+ self . end_block ( ) ;
123
119
124
- // generate and push genesis block
125
- let genesis_block = self . host . generate_block ( app_hash, 1 , genesis_time, params) ;
126
- self . host . push_block ( genesis_block) ;
120
+ // commit multi store
121
+ let multi_store_commitment = self . multi_store . commit ( ) . expect ( "no error" ) ;
127
122
128
- // store it in ibc context as host consensus state
129
- self . ibc_store . store_host_consensus_state (
123
+ // generate a genesis block
124
+ let genesis_block =
130
125
self . host
131
- . latest_block ( )
132
- . into_header ( )
133
- . into_consensus_state ( )
134
- . into ( ) ,
126
+ . generate_block ( multi_store_commitment, 1 , genesis_time, params) ;
127
+
128
+ // push the genesis block to the host
129
+ self . host . push_block ( genesis_block) ;
130
+
131
+ self . begin_block ( ) ;
132
+ }
133
+
134
+ pub fn begin_block ( & mut self ) {
135
+ let consensus_state = self
136
+ . host
137
+ . latest_block ( )
138
+ . into_header ( )
139
+ . into_consensus_state ( )
140
+ . into ( ) ;
141
+
142
+ let ibc_commitment_proof = self
143
+ . multi_store
144
+ . get_proof (
145
+ self . host . latest_height ( ) . revision_height ( ) . into ( ) ,
146
+ & self
147
+ . ibc_store
148
+ . commitment_prefix ( )
149
+ . as_bytes ( )
150
+ . try_into ( )
151
+ . expect ( "valid utf8 prefix" ) ,
152
+ )
153
+ . expect ( "no error" ) ;
154
+
155
+ self . ibc_store . begin_block (
156
+ self . host . latest_height ( ) . revision_height ( ) ,
157
+ consensus_state,
158
+ ibc_commitment_proof,
135
159
) ;
136
160
}
137
161
138
- pub fn advance_with_block_params ( & mut self , block_time : Duration , params : & H :: BlockParams ) {
139
- // commit store
140
- let app_hash = self . ibc_store . commit ( ) . expect ( "no error" ) ;
162
+ pub fn end_block ( & mut self ) {
163
+ // commit ibc store
164
+ let ibc_store_commitment = self . ibc_store . end_block ( ) . expect ( "no error" ) ;
165
+
166
+ // commit ibc store commitment in multi store
167
+ self . multi_store
168
+ . set (
169
+ self . ibc_store
170
+ . commitment_prefix ( )
171
+ . as_bytes ( )
172
+ . try_into ( )
173
+ . expect ( "valid utf8 prefix" ) ,
174
+ ibc_store_commitment,
175
+ )
176
+ . expect ( "no error" ) ;
177
+ }
141
178
179
+ pub fn produce_block ( & mut self , block_time : Duration , params : & H :: BlockParams ) {
180
+ // commit the multi store
181
+ let multi_store_commitment = self . multi_store . commit ( ) . expect ( "no error" ) ;
142
182
// generate a new block
143
- self . host . advance_block ( app_hash, block_time, params) ;
183
+ self . host
184
+ . advance_block ( multi_store_commitment, block_time, params) ;
185
+ }
144
186
145
- // store it in ibc context as host consensus state
146
- self . ibc_store . store_host_consensus_state (
147
- self . host
148
- . latest_block ( )
149
- . into_header ( )
150
- . into_consensus_state ( )
151
- . into ( ) ,
152
- ) ;
187
+ pub fn advance_with_block_params ( & mut self , block_time : Duration , params : & H :: BlockParams ) {
188
+ self . end_block ( ) ;
189
+ self . produce_block ( block_time, params) ;
190
+ self . begin_block ( ) ;
153
191
}
154
192
155
193
pub fn advance_block ( & mut self ) {
@@ -355,12 +393,9 @@ where
355
393
/// A datagram passes from the relayer to the IBC module (on host chain).
356
394
/// Alternative method to `Ics18Context::send` that does not exercise any serialization.
357
395
/// Used in testing the Ics18 algorithms, hence this may return a Ics18Error.
358
- pub fn deliver (
359
- & mut self ,
360
- router : & mut impl Router ,
361
- msg : MsgEnvelope ,
362
- ) -> Result < ( ) , RelayerError > {
363
- dispatch ( & mut self . ibc_store , router, msg) . map_err ( RelayerError :: TransactionFailed ) ?;
396
+ pub fn deliver ( & mut self , msg : MsgEnvelope ) -> Result < ( ) , RelayerError > {
397
+ dispatch ( & mut self . ibc_store , & mut self . ibc_router , msg)
398
+ . map_err ( RelayerError :: TransactionFailed ) ?;
364
399
// Create a new block.
365
400
self . advance_block ( ) ;
366
401
Ok ( ( ) )
0 commit comments