Skip to content

Commit 597c787

Browse files
authored
Fix OOM error in large parentchain syncs with sidechain feature. (#1493)
* improve log levels * [service] `sidechain_start_untrusted_rpc_server`downgrade tokyo handle arg to a borrow * [service/main] distinguish better between different setups * [service/main] extract duplicate code * [service/main] fix clippy * [service/main] fix clippy with teeracle * introduce `is_syncing` in `sync_parentchain` * remove obsolete `trigger_parentchain_block` ffi * remove unused import * fix clippy * fix test compilation * [service/main] extract `init_proxied_shard_vault`
1 parent 60ef825 commit 597c787

File tree

12 files changed

+210
-254
lines changed

12 files changed

+210
-254
lines changed

core-primitives/enclave-api/ffi/src/lib.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,6 @@ extern "C" {
6666
parentchain_id_size: u32,
6767
) -> sgx_status_t;
6868

69-
pub fn trigger_parentchain_block_import(
70-
eid: sgx_enclave_id_t,
71-
retval: *mut sgx_status_t,
72-
parentchain_id: *const u8,
73-
parentchain_id_size: u32,
74-
) -> sgx_status_t;
75-
7669
pub fn execute_trusted_calls(eid: sgx_enclave_id_t, retval: *mut sgx_status_t) -> sgx_status_t;
7770

7871
pub fn sync_parentchain(
@@ -86,6 +79,7 @@ extern "C" {
8679
events_proofs_size: usize,
8780
parentchain_id: *const u8,
8881
parentchain_id_size: u32,
82+
is_syncing: c_int,
8983
) -> sgx_status_t;
9084

9185
pub fn set_nonce(

core-primitives/enclave-api/src/enclave_base.rs

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,6 @@ pub trait EnclaveBase: Send + Sync + 'static {
5757
parentchain_id: &ParentchainId,
5858
) -> EnclaveResult<()>;
5959

60-
/// Trigger the import of parentchain block explicitly. Used when initializing a light-client
61-
/// with a triggered import dispatcher.
62-
fn trigger_parentchain_block_import(&self, parentchain_id: &ParentchainId)
63-
-> EnclaveResult<()>;
64-
6560
fn set_nonce(&self, nonce: u32, parentchain_id: ParentchainId) -> EnclaveResult<()>;
6661

6762
fn set_node_metadata(
@@ -212,27 +207,6 @@ mod impl_ffi {
212207

213208
Ok(())
214209
}
215-
fn trigger_parentchain_block_import(
216-
&self,
217-
parentchain_id: &ParentchainId,
218-
) -> EnclaveResult<()> {
219-
let mut retval = sgx_status_t::SGX_SUCCESS;
220-
let parentchain_id_enc = parentchain_id.encode();
221-
222-
let result = unsafe {
223-
ffi::trigger_parentchain_block_import(
224-
self.eid,
225-
&mut retval,
226-
parentchain_id_enc.as_ptr(),
227-
parentchain_id_enc.len() as u32,
228-
)
229-
};
230-
231-
ensure!(result == sgx_status_t::SGX_SUCCESS, Error::Sgx(result));
232-
ensure!(retval == sgx_status_t::SGX_SUCCESS, Error::Sgx(retval));
233-
234-
Ok(())
235-
}
236210

237211
fn set_nonce(&self, nonce: u32, parentchain_id: ParentchainId) -> EnclaveResult<()> {
238212
let mut retval = sgx_status_t::SGX_SUCCESS;

core-primitives/enclave-api/src/sidechain.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ pub trait Sidechain: Send + Sync + 'static {
3232
events: &[Vec<u8>],
3333
events_proofs: &[StorageProof],
3434
parentchain_id: &ParentchainId,
35+
is_syncing: bool,
3536
) -> EnclaveResult<()>;
3637

3738
fn execute_trusted_calls(&self) -> EnclaveResult<()>;
@@ -56,6 +57,7 @@ mod impl_ffi {
5657
events: &[Vec<u8>],
5758
events_proofs: &[StorageProof],
5859
parentchain_id: &ParentchainId,
60+
is_syncing: bool,
5961
) -> EnclaveResult<()> {
6062
let mut retval = sgx_status_t::SGX_SUCCESS;
6163
let blocks_enc = blocks.encode();
@@ -75,6 +77,7 @@ mod impl_ffi {
7577
events_proofs_enc.len(),
7678
parentchain_id_enc.as_ptr(),
7779
parentchain_id_enc.len() as u32,
80+
is_syncing.into(),
7881
)
7982
};
8083

core/parentchain/block-import-dispatcher/src/immediate_dispatcher.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,14 @@ impl<BlockImporter, SignedBlockType> DispatchBlockImport<SignedBlockType>
4747
where
4848
BlockImporter: ImportParentchainBlocks<SignedBlockType = SignedBlockType>,
4949
{
50-
fn dispatch_import(&self, blocks: Vec<SignedBlockType>, events: Vec<Vec<u8>>) -> Result<()> {
50+
fn dispatch_import(
51+
&self,
52+
blocks: Vec<SignedBlockType>,
53+
events: Vec<Vec<u8>>,
54+
_is_syncing: bool,
55+
) -> Result<()> {
56+
// _is_syncing does not matter for the immediate dispatcher, behavoiur is the same. Immediate block import.
57+
5158
debug!("Importing {} parentchain blocks", blocks.len());
5259
self.block_importer.import_parentchain_blocks(blocks, events)?;
5360
debug!("Notifying {} observers of import", self.import_event_observers.len());
@@ -93,7 +100,7 @@ mod tests {
93100
counter_clone.increment();
94101
});
95102

96-
dispatcher.dispatch_import(vec![1u32, 2u32], vec![]).unwrap();
103+
dispatcher.dispatch_import(vec![1u32, 2u32], vec![], false).unwrap();
97104

98105
assert_eq!(1, notification_counter.get_counter());
99106
}

core/parentchain/block-import-dispatcher/src/lib.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,12 @@ pub trait DispatchBlockImport<SignedBlockType> {
4545
/// Dispatch blocks to be imported.
4646
///
4747
/// The blocks may be imported immediately, get queued, delayed or grouped.
48-
fn dispatch_import(&self, blocks: Vec<SignedBlockType>, events: Vec<Vec<u8>>) -> Result<()>;
48+
fn dispatch_import(
49+
&self,
50+
blocks: Vec<SignedBlockType>,
51+
events: Vec<Vec<u8>>,
52+
is_syncing: bool,
53+
) -> Result<()>;
4954
}
5055

5156
/// Wrapper for the actual dispatchers. Allows to define one global type for
@@ -96,15 +101,20 @@ where
96101
TriggeredDispatcher: DispatchBlockImport<SignedBlockType>,
97102
ImmediateDispatcher: DispatchBlockImport<SignedBlockType>,
98103
{
99-
fn dispatch_import(&self, blocks: Vec<SignedBlockType>, events: Vec<Vec<u8>>) -> Result<()> {
104+
fn dispatch_import(
105+
&self,
106+
blocks: Vec<SignedBlockType>,
107+
events: Vec<Vec<u8>>,
108+
is_syncing: bool,
109+
) -> Result<()> {
100110
match self {
101111
BlockImportDispatcher::TriggeredDispatcher(dispatcher) => {
102112
log::trace!("TRIGGERED DISPATCHER MATCH");
103-
dispatcher.dispatch_import(blocks, events)
113+
dispatcher.dispatch_import(blocks, events, is_syncing)
104114
},
105115
BlockImportDispatcher::ImmediateDispatcher(dispatcher) => {
106116
log::trace!("IMMEDIATE DISPATCHER MATCH");
107-
dispatcher.dispatch_import(blocks, events)
117+
dispatcher.dispatch_import(blocks, events, is_syncing)
108118
},
109119
BlockImportDispatcher::EmptyDispatcher => {
110120
log::trace!("EMPTY DISPATCHER DISPATCHER MATCH");

core/parentchain/block-import-dispatcher/src/triggered_dispatcher.rs

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -100,17 +100,28 @@ where
100100
&self,
101101
blocks: Vec<SignedBlockType>,
102102
events: Vec<RawEventsPerBlock>,
103+
is_syncing: bool,
103104
) -> Result<()> {
104105
let parentchain_id = self.block_importer.parentchain_id();
105106
trace!(
106-
"[{:?}] Pushing parentchain block(s) and event(s) ({}) ({}) to import queue",
107+
"[{:?}] Triggered dispatcher received block(s) and event(s) ({}) ({})",
107108
parentchain_id,
108109
blocks.len(),
109110
events.len()
110111
);
111-
// Push all the blocks to be dispatched into the queue.
112-
self.events_queue.push_multiple(events).map_err(Error::ImportQueue)?;
113-
self.import_queue.push_multiple(blocks).map_err(Error::ImportQueue)
112+
if is_syncing {
113+
trace!(
114+
"[{:?}] Triggered is in sync mode, immediately importing blocks and events",
115+
parentchain_id
116+
);
117+
self.block_importer
118+
.import_parentchain_blocks(blocks, events)
119+
.map_err(Error::BlockImport)
120+
} else {
121+
trace!("[{:?}] pushing blocks and events to import queues", parentchain_id);
122+
self.events_queue.push_multiple(events).map_err(Error::ImportQueue)?;
123+
self.import_queue.push_multiple(blocks).map_err(Error::ImportQueue)
124+
}
114125
}
115126
}
116127

@@ -167,6 +178,7 @@ where
167178
&self,
168179
predicate: impl Fn(&BlockImporter::SignedBlockType) -> bool,
169180
) -> Result<Option<BlockImporter::SignedBlockType>> {
181+
trace!("Import of parentchain blocks and events has been triggered");
170182
let blocks_to_import =
171183
self.import_queue.pop_until(predicate).map_err(Error::ImportQueue)?;
172184

@@ -232,7 +244,11 @@ mod tests {
232244
let dispatcher = test_fixtures();
233245

234246
dispatcher
235-
.dispatch_import(vec![1, 2, 3, 4, 5], vec![vec![1], vec![2], vec![3], vec![4], vec![5]])
247+
.dispatch_import(
248+
vec![1, 2, 3, 4, 5],
249+
vec![vec![1], vec![2], vec![3], vec![4], vec![5]],
250+
false,
251+
)
236252
.unwrap();
237253

238254
assert!(dispatcher.block_importer.get_all_imported_blocks().is_empty());
@@ -248,10 +264,14 @@ mod tests {
248264
let dispatcher = test_fixtures();
249265

250266
dispatcher
251-
.dispatch_import(vec![1, 2, 3, 4, 5], vec![vec![1], vec![2], vec![3], vec![4], vec![5]])
267+
.dispatch_import(
268+
vec![1, 2, 3, 4, 5],
269+
vec![vec![1], vec![2], vec![3], vec![4], vec![5]],
270+
false,
271+
)
252272
.unwrap();
253273
dispatcher
254-
.dispatch_import(vec![6, 7, 8], vec![vec![6], vec![7], vec![8]])
274+
.dispatch_import(vec![6, 7, 8], vec![vec![6], vec![7], vec![8]], false)
255275
.unwrap();
256276

257277
assert!(dispatcher.block_importer.get_all_imported_blocks().is_empty());
@@ -266,7 +286,7 @@ mod tests {
266286
fn triggering_import_all_empties_queue() {
267287
let dispatcher = test_fixtures();
268288

269-
dispatcher.dispatch_import(vec![1, 2, 3, 4, 5], vec![]).unwrap();
289+
dispatcher.dispatch_import(vec![1, 2, 3, 4, 5], vec![], false).unwrap();
270290
let latest_imported = dispatcher.import_all().unwrap().unwrap();
271291

272292
assert_eq!(latest_imported, 5);
@@ -278,7 +298,7 @@ mod tests {
278298
fn triggering_import_all_on_empty_queue_imports_none() {
279299
let dispatcher = test_fixtures();
280300

281-
dispatcher.dispatch_import(vec![], vec![]).unwrap();
301+
dispatcher.dispatch_import(vec![], vec![], false).unwrap();
282302
let maybe_latest_imported = dispatcher.import_all().unwrap();
283303

284304
assert!(maybe_latest_imported.is_none());
@@ -295,7 +315,11 @@ mod tests {
295315
let dispatcher = test_fixtures();
296316

297317
dispatcher
298-
.dispatch_import(vec![1, 2, 3, 4, 5], vec![vec![1], vec![2], vec![3], vec![4], vec![5]])
318+
.dispatch_import(
319+
vec![1, 2, 3, 4, 5],
320+
vec![vec![1], vec![2], vec![3], vec![4], vec![5]],
321+
false,
322+
)
299323
.unwrap();
300324
let latest_imported =
301325
dispatcher.import_until(|i: &SignedBlockType| i == &4).unwrap().unwrap();
@@ -311,7 +335,11 @@ mod tests {
311335
let dispatcher = test_fixtures();
312336

313337
dispatcher
314-
.dispatch_import(vec![1, 2, 3, 4, 5], vec![vec![1], vec![2], vec![3], vec![4], vec![5]])
338+
.dispatch_import(
339+
vec![1, 2, 3, 4, 5],
340+
vec![vec![1], vec![2], vec![3], vec![4], vec![5]],
341+
false,
342+
)
315343
.unwrap();
316344
let maybe_latest_imported = dispatcher.import_until(|i: &SignedBlockType| i == &8).unwrap();
317345

@@ -328,7 +356,7 @@ mod tests {
328356
fn trigger_import_all_but_latest_works() {
329357
let dispatcher = test_fixtures();
330358

331-
dispatcher.dispatch_import(vec![1, 2, 3, 4, 5], vec![]).unwrap();
359+
dispatcher.dispatch_import(vec![1, 2, 3, 4, 5], vec![], false).unwrap();
332360
dispatcher.import_all_but_latest().unwrap();
333361

334362
assert_eq!(dispatcher.block_importer.get_all_imported_blocks(), vec![1, 2, 3, 4]);

enclave-runtime/Enclave.edl

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,14 @@ enclave {
6363
[in, size=parentchain_id_size] uint8_t* parentchain_id, uint32_t parentchain_id_size
6464
);
6565

66-
public sgx_status_t trigger_parentchain_block_import(
67-
[in, size=parentchain_id_size] uint8_t* parentchain_id, uint32_t parentchain_id_size
68-
);
69-
7066
public sgx_status_t execute_trusted_calls();
7167

7268
public sgx_status_t sync_parentchain(
7369
[in, size=blocks_size] uint8_t* blocks, size_t blocks_size,
7470
[in, size=events_size] uint8_t* events, size_t events_size,
7571
[in, size=events_proofs_size] uint8_t* events_proofs, size_t events_proofs_size,
76-
[in, size=parentchain_id_size] uint8_t* parentchain_id, uint32_t parentchain_id_size
72+
[in, size=parentchain_id_size] uint8_t* parentchain_id, uint32_t parentchain_id_size,
73+
int is_syncing
7774
);
7875

7976
public sgx_status_t set_nonce(

0 commit comments

Comments
 (0)