Skip to content

Commit 39004a2

Browse files
authored
Fix the restored_rw_ids indexing in recording mode. (#1591)
### What Fix the restored_rw_ids indexing in recording mode. This incorrectly increased the counter only for the existent entries. Unfortunately, this hasn't been caught by any tests before because no tests created new entries in combination with autorestore. ### Why Simulation fix. ### Known limitations N/A
1 parent a75e5c7 commit 39004a2

File tree

2 files changed

+146
-3
lines changed

2 files changed

+146
-3
lines changed

soroban-env-host/src/e2e_invoke.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -766,9 +766,9 @@ pub fn invoke_host_function_in_recording_mode(
766766
} else {
767767
encoded_ttl_entries.push(vec![]);
768768
}
769-
if matches!(*access_type, AccessType::ReadWrite) {
770-
current_rw_id += 1;
771-
}
769+
}
770+
if matches!(*access_type, AccessType::ReadWrite) {
771+
current_rw_id += 1;
772772
}
773773
}
774774
let (init_storage, init_ttl_map) = build_storage_map_from_xdr_ledger_entries(

soroban-env-host/src/test/e2e_tests.rs

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2530,6 +2530,149 @@ fn test_auto_restore_with_overwrite_in_recording_mode() {
25302530
.unwrap();
25312531
}
25322532

2533+
#[test]
2534+
fn test_auto_restore_with_new_entry_in_recording_mode() {
2535+
let cd = CreateContractData::new([111; 32], CONTRACT_STORAGE);
2536+
let ledger_info = default_ledger_info();
2537+
2538+
let key = symbol_sc_val("key");
2539+
let val = u64_sc_val(u64::MAX);
2540+
let host_fn = invoke_contract_host_fn(
2541+
&cd.contract_address,
2542+
"put_persistent",
2543+
vec![key.clone(), val.clone()],
2544+
);
2545+
2546+
let data_key = contract_data_key(
2547+
&cd.contract_address,
2548+
&key,
2549+
ContractDataDurability::Persistent,
2550+
);
2551+
let le_with_ttl = vec![
2552+
(
2553+
cd.wasm_entry.clone(),
2554+
Some(ledger_info.sequence_number - 100_000),
2555+
),
2556+
(
2557+
cd.contract_entry.clone(),
2558+
Some(ledger_info.sequence_number - 100),
2559+
),
2560+
];
2561+
let res = invoke_host_function_recording_helper(
2562+
true,
2563+
&host_fn,
2564+
&cd.deployer,
2565+
RecordingInvocationAuthMode::Recording(true),
2566+
&ledger_info,
2567+
le_with_ttl.clone(),
2568+
&prng_seed(),
2569+
None,
2570+
)
2571+
.unwrap();
2572+
assert_eq!(res.invoke_result.unwrap(), ScVal::Void);
2573+
assert!(res.contract_events.is_empty());
2574+
assert_eq!(res.restored_rw_entry_ids.len(), 2);
2575+
assert_eq!(
2576+
res.resources.footprint.read_write[res.restored_rw_entry_ids[0] as usize],
2577+
cd.contract_key
2578+
);
2579+
assert_eq!(
2580+
res.resources.footprint.read_write[res.restored_rw_entry_ids[1] as usize],
2581+
cd.wasm_key
2582+
);
2583+
2584+
let expected_persistent_data_entry = contract_data_entry(
2585+
&cd.contract_address,
2586+
&key,
2587+
&val,
2588+
ContractDataDurability::Persistent,
2589+
);
2590+
let data_entry_size = expected_persistent_data_entry
2591+
.to_xdr(Limits::none())
2592+
.unwrap()
2593+
.len() as u32;
2594+
let instance_entry_size = cd.contract_entry.to_xdr(Limits::none()).unwrap().len() as u32;
2595+
assert_eq!(
2596+
res.ledger_changes,
2597+
vec![
2598+
LedgerEntryChangeHelper {
2599+
read_only: false,
2600+
key: data_key.clone(),
2601+
old_entry_size_bytes_for_rent: 0,
2602+
new_value: Some(expected_persistent_data_entry.clone()),
2603+
ttl_change: Some(LedgerEntryLiveUntilChange {
2604+
key_hash: compute_key_hash(&data_key),
2605+
entry_type: LedgerEntryType::ContractData,
2606+
durability: ContractDataDurability::Persistent,
2607+
old_live_until_ledger: 0,
2608+
new_live_until_ledger: ledger_info.sequence_number
2609+
+ ledger_info.min_persistent_entry_ttl
2610+
- 1,
2611+
}),
2612+
},
2613+
LedgerEntryChangeHelper {
2614+
read_only: false,
2615+
key: cd.contract_key.clone(),
2616+
old_entry_size_bytes_for_rent: 0,
2617+
new_value: Some(cd.contract_entry.clone()),
2618+
ttl_change: Some(LedgerEntryLiveUntilChange {
2619+
key_hash: compute_key_hash(&cd.contract_key),
2620+
entry_type: LedgerEntryType::ContractData,
2621+
durability: ContractDataDurability::Persistent,
2622+
old_live_until_ledger: 0,
2623+
new_live_until_ledger: ledger_info.sequence_number
2624+
+ ledger_info.min_persistent_entry_ttl
2625+
- 1,
2626+
}),
2627+
},
2628+
LedgerEntryChangeHelper {
2629+
read_only: false,
2630+
key: cd.wasm_key.clone(),
2631+
old_entry_size_bytes_for_rent: 0,
2632+
new_value: Some(cd.wasm_entry.clone()),
2633+
ttl_change: Some(LedgerEntryLiveUntilChange {
2634+
key_hash: compute_key_hash(&cd.wasm_key),
2635+
entry_type: LedgerEntryType::ContractCode,
2636+
durability: ContractDataDurability::Persistent,
2637+
old_live_until_ledger: 0,
2638+
new_live_until_ledger: ledger_info.sequence_number
2639+
+ ledger_info.min_persistent_entry_ttl
2640+
- 1,
2641+
}),
2642+
},
2643+
]
2644+
);
2645+
let wasm_entry_size = cd.wasm_entry.to_xdr(Limits::none()).unwrap().len() as u32;
2646+
assert_eq!(
2647+
res.resources,
2648+
SorobanResources {
2649+
footprint: LedgerFootprint {
2650+
read_only: vec![].try_into().unwrap(),
2651+
read_write: vec![
2652+
data_key.clone(),
2653+
cd.contract_key.clone(),
2654+
cd.wasm_key.clone(),
2655+
]
2656+
.try_into()
2657+
.unwrap(),
2658+
},
2659+
instructions: 1444181,
2660+
disk_read_bytes: wasm_entry_size + instance_entry_size,
2661+
write_bytes: data_entry_size + wasm_entry_size + instance_entry_size,
2662+
}
2663+
);
2664+
2665+
let _ = invoke_host_function_using_simulation(
2666+
true,
2667+
&host_fn,
2668+
&cd.deployer,
2669+
&ledger_info,
2670+
le_with_ttl,
2671+
&prng_seed(),
2672+
)
2673+
.unwrap();
2674+
}
2675+
25332676
#[test]
25342677
fn test_auto_restore_with_expired_temp_entry_in_recording_mode() {
25352678
let cd = CreateContractData::new([111; 32], CONTRACT_STORAGE);

0 commit comments

Comments
 (0)