Skip to content

Commit 706000f

Browse files
committed
various improvements to align contract bytecode retrieval and state retrieval
1 parent 658b245 commit 706000f

File tree

1 file changed

+102
-66
lines changed
  • forc-plugins/forc-node/src/local

1 file changed

+102
-66
lines changed

forc-plugins/forc-node/src/local/fork.rs

Lines changed: 102 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,10 @@ impl ForkClient {
8484
.contract_slots_values(&contract_id, block_height, vec![key])
8585
.await
8686
}) {
87-
Ok(slot_values) => {
88-
for (slot_key, slot_value) in slot_values {
89-
if slot_key == key {
90-
return Ok(Some(slot_value));
91-
}
92-
}
93-
Ok(None)
94-
}
87+
Ok(slot_values) => Ok(slot_values
88+
.into_iter()
89+
.find(|(slot_key, _)| *slot_key == key)
90+
.map(|(_, slot_value)| slot_value)),
9591
Err(e) => {
9692
tracing::debug!("Failed to fetch contract state: {}", e);
9793
Ok(None)
@@ -270,19 +266,36 @@ where
270266
if self.inner.exists(key, column)? {
271267
return Ok(true);
272268
}
273-
274-
if column == Column::ContractsRawCode {
275-
if let Ok(contract_id) = key.try_into() {
276-
let fork_client = self.fork_client.clone();
277-
match fork_client.fetch_contract_bytecode_blocking(&contract_id) {
278-
Ok(Some(_)) => Ok(true),
279-
_ => Ok(false),
269+
match column {
270+
Column::ContractsRawCode => {
271+
if let Ok(contract_id) = key[..32].try_into() {
272+
let exists = self
273+
.fork_client
274+
.fetch_contract_bytecode_blocking(&contract_id)
275+
.map(|opt| opt.is_some())
276+
.unwrap_or(false);
277+
Ok(exists)
278+
} else {
279+
Ok(false)
280280
}
281-
} else {
282-
Ok(false)
283281
}
284-
} else {
285-
Ok(false)
282+
Column::ContractsState if key.len() == 64 => {
283+
if let Ok(contract_id) = key[..32].try_into() {
284+
if let Ok(state_key) = key[32..64].try_into() {
285+
let exists = self
286+
.fork_client
287+
.fetch_contract_state_blocking(&contract_id, &state_key)
288+
.map(|opt| opt.is_some())
289+
.unwrap_or(false);
290+
Ok(exists)
291+
} else {
292+
Ok(false)
293+
}
294+
} else {
295+
Ok(false)
296+
}
297+
}
298+
_ => Ok(false),
286299
}
287300
}
288301
_ => self.inner.exists(key, column),
@@ -296,11 +309,28 @@ where
296309

297310
match column {
298311
Column::ContractsRawCode => {
299-
if let Ok(contract_id) = key.try_into() {
300-
let fork_client = self.fork_client.clone();
301-
match fork_client.fetch_contract_bytecode_blocking(&contract_id) {
302-
Ok(Some(bytecode)) => Ok(Some(bytecode.len())),
303-
_ => Ok(None),
312+
if let Ok(contract_id) = key[..32].try_into() {
313+
let size = self
314+
.fork_client
315+
.fetch_contract_bytecode_blocking(&contract_id)
316+
.map(|opt| opt.map(|bytecode| bytecode.len()))
317+
.unwrap_or(None);
318+
Ok(size)
319+
} else {
320+
Ok(None)
321+
}
322+
}
323+
Column::ContractsState if key.len() == 64 => {
324+
if let Ok(contract_id) = key[..32].try_into() {
325+
if let Ok(state_key) = key[32..64].try_into() {
326+
let size = self
327+
.fork_client
328+
.fetch_contract_state_blocking(&contract_id, &state_key)
329+
.map(|opt| opt.map(|state| state.len()))
330+
.unwrap_or(None);
331+
Ok(size)
332+
} else {
333+
Ok(None)
304334
}
305335
} else {
306336
Ok(None)
@@ -325,13 +355,15 @@ where
325355

326356
match column {
327357
Column::ContractsRawCode => {
328-
if let Ok(contract_id) = key.try_into() {
358+
if let Ok(contract_id) = key[..32].try_into() {
329359
tracing::info!(
330360
"ForkedView: Attempting to fetch contract {} from fork",
331361
contract_id
332362
);
333-
let fork_client = self.fork_client.clone();
334-
match fork_client.fetch_contract_bytecode_blocking(&contract_id) {
363+
match self
364+
.fork_client
365+
.fetch_contract_bytecode_blocking(&contract_id)
366+
{
335367
Ok(Some(bytecode)) => {
336368
tracing::info!(
337369
"ForkedView: Successfully fetched contract {} from fork",
@@ -364,32 +396,14 @@ where
364396
Ok(None)
365397
}
366398
}
367-
Column::ContractsAssets => Ok(None),
368-
Column::ContractsState => {
369-
if key.len() >= 64 {
370-
let contract_bytes = &key[..32];
371-
let state_key_bytes = &key[32..64];
372-
373-
if let (Ok(contract_bytes), Ok(state_key_bytes)) = (
374-
<[u8; 32]>::try_from(contract_bytes),
375-
<[u8; 32]>::try_from(state_key_bytes),
376-
) {
377-
let contract_id = ContractId::from(contract_bytes);
378-
let state_key = Bytes32::from(state_key_bytes);
379-
tracing::info!(
380-
"ForkedView: Attempting to fetch state for contract {} key {} from fork",
381-
contract_id,
382-
state_key
383-
);
384-
let fork_client = self.fork_client.clone();
385-
386-
match fork_client.fetch_contract_state_blocking(&contract_id, &state_key) {
399+
Column::ContractsState if key.len() == 64 => {
400+
if let Ok(contract_id) = key[..32].try_into() {
401+
if let Ok(state_key) = key[32..64].try_into() {
402+
match self
403+
.fork_client
404+
.fetch_contract_state_blocking(&contract_id, &state_key)
405+
{
387406
Ok(Some(state_data)) => {
388-
tracing::info!(
389-
"ForkedView: Successfully fetched state for contract {} key {} from fork",
390-
contract_id,
391-
state_key
392-
);
393407
let mut storage_key = Vec::with_capacity(
394408
contract_id.as_ref().len() + state_key.as_ref().len(),
395409
);
@@ -412,26 +426,22 @@ where
412426
}
413427
Err(e) => {
414428
tracing::warn!(
415-
"ForkedView: Error fetching state for contract {} key {} from fork: {}",
416-
contract_id,
417-
state_key,
418-
e
419-
);
429+
"ForkedView: Error fetching state for contract {} key {} from fork: {}",
430+
contract_id,
431+
state_key,
432+
e
433+
);
420434
Err(fuel_core_storage::Error::Other(e))
421435
}
422436
}
423437
} else {
424-
tracing::warn!("ForkedView: Failed to parse ContractsState key");
425438
Ok(None)
426439
}
427440
} else {
428-
tracing::warn!(
429-
"ForkedView: ContractsState key too short: {} bytes",
430-
key.len()
431-
);
432441
Ok(None)
433442
}
434443
}
444+
Column::ContractsAssets => Ok(None),
435445
_ => Ok(None),
436446
}
437447
}
@@ -449,10 +459,11 @@ where
449459

450460
match column {
451461
Column::ContractsRawCode => {
452-
if let Ok(contract_id) = key.try_into() {
453-
let fork_client = self.fork_client.clone();
454-
455-
match fork_client.fetch_contract_bytecode_blocking(&contract_id) {
462+
if let Ok(contract_id) = key[..32].try_into() {
463+
match self
464+
.fork_client
465+
.fetch_contract_bytecode_blocking(&contract_id)
466+
{
456467
Ok(Some(bytecode)) => {
457468
if offset >= bytecode.len() {
458469
return Ok(false);
@@ -468,6 +479,31 @@ where
468479
Ok(false)
469480
}
470481
}
482+
Column::ContractsState if key.len() == 64 => {
483+
if let Ok(contract_id) = key[..32].try_into() {
484+
if let Ok(state_key) = key[32..64].try_into() {
485+
match self
486+
.fork_client
487+
.fetch_contract_state_blocking(&contract_id, &state_key)
488+
{
489+
Ok(Some(state_data)) => {
490+
if offset >= state_data.len() {
491+
return Ok(false);
492+
}
493+
let available = state_data.len() - offset;
494+
let len = available.min(buf.len());
495+
buf[..len].copy_from_slice(&state_data[offset..offset + len]);
496+
Ok(true)
497+
}
498+
_ => Ok(false),
499+
}
500+
} else {
501+
Ok(false)
502+
}
503+
} else {
504+
Ok(false)
505+
}
506+
}
471507
_ => Ok(false),
472508
}
473509
}

0 commit comments

Comments
 (0)