diff --git a/script/src/syscalls/load_cell_data.rs b/script/src/syscalls/load_cell_data.rs
index 11adfadca7..5147e44f8d 100644
--- a/script/src/syscalls/load_cell_data.rs
+++ b/script/src/syscalls/load_cell_data.rs
@@ -1,86 +1,73 @@
-use crate::types::Indices;
+use crate::v2_types::{DataPieceId, TxData};
use crate::{
cost_model::transferred_byte_cycles,
syscalls::{
- utils::store_data, Source, SourceEntry, INDEX_OUT_OF_BOUND,
- LOAD_CELL_DATA_AS_CODE_SYSCALL_NUMBER, LOAD_CELL_DATA_SYSCALL_NUMBER, SLICE_OUT_OF_BOUND,
- SUCCESS,
+ INDEX_OUT_OF_BOUND, LOAD_CELL_DATA_AS_CODE_SYSCALL_NUMBER, LOAD_CELL_DATA_SYSCALL_NUMBER,
+ SLICE_OUT_OF_BOUND, SUCCESS,
},
};
-use ckb_traits::CellDataProvider;
-use ckb_types::core::cell::{CellMeta, ResolvedTransaction};
+use ckb_traits::{CellDataProvider, ExtensionProvider, HeaderProvider};
use ckb_vm::{
memory::{Memory, FLAG_EXECUTABLE, FLAG_FREEZED},
registers::{A0, A1, A2, A3, A4, A5, A7},
+ snapshot2::{DataSource, Snapshot2Context},
Error as VMError, Register, SupportMachine, Syscalls,
};
-use std::sync::Arc;
+use std::sync::{Arc, Mutex};
-pub struct LoadCellData
{
- data_loader: DL,
- rtx: Arc,
- outputs: Arc>,
- group_inputs: Indices,
- group_outputs: Indices,
+pub struct LoadCellData
+where
+ DL: CellDataProvider + HeaderProvider + ExtensionProvider + Send + Sync + Clone + 'static,
+{
+ snapshot2_context: Arc>>>,
}
-impl LoadCellData {
+impl LoadCellData
+where
+ DL: CellDataProvider + HeaderProvider + ExtensionProvider + Send + Sync + Clone + 'static,
+{
pub fn new(
- data_loader: DL,
- rtx: Arc,
- outputs: Arc>,
- group_inputs: Indices,
- group_outputs: Indices,
+ snapshot2_context: Arc>>>,
) -> LoadCellData {
- LoadCellData {
- data_loader,
- rtx,
- outputs,
- group_inputs,
- group_outputs,
- }
- }
-
- #[inline]
- fn resolved_inputs(&self) -> &Vec {
- &self.rtx.resolved_inputs
- }
-
- #[inline]
- fn resolved_cell_deps(&self) -> &Vec {
- &self.rtx.resolved_cell_deps
+ LoadCellData { snapshot2_context }
}
- fn fetch_cell(&self, source: Source, index: usize) -> Result<&CellMeta, u8> {
- match source {
- Source::Transaction(SourceEntry::Input) => {
- self.resolved_inputs().get(index).ok_or(INDEX_OUT_OF_BOUND)
- }
- Source::Transaction(SourceEntry::Output) => {
- self.outputs.get(index).ok_or(INDEX_OUT_OF_BOUND)
+ fn load_data(&self, machine: &mut Mac) -> Result<(), VMError> {
+ let index = machine.registers()[A3].to_u64();
+ let source = machine.registers()[A4].to_u64();
+ let data_piece_id = match DataPieceId::try_from((source, index, 0)) {
+ Ok(id) => id,
+ Err(_) => {
+ machine.set_register(A0, Mac::REG::from_u8(INDEX_OUT_OF_BOUND));
+ return Ok(());
}
- Source::Transaction(SourceEntry::CellDep) => self
- .resolved_cell_deps()
- .get(index)
- .ok_or(INDEX_OUT_OF_BOUND),
- Source::Transaction(SourceEntry::HeaderDep) => Err(INDEX_OUT_OF_BOUND),
- Source::Group(SourceEntry::Input) => self
- .group_inputs
- .get(index)
- .ok_or(INDEX_OUT_OF_BOUND)
- .and_then(|actual_index| {
- self.resolved_inputs()
- .get(*actual_index)
- .ok_or(INDEX_OUT_OF_BOUND)
- }),
- Source::Group(SourceEntry::Output) => self
- .group_outputs
- .get(index)
- .ok_or(INDEX_OUT_OF_BOUND)
- .and_then(|actual_index| self.outputs.get(*actual_index).ok_or(INDEX_OUT_OF_BOUND)),
- Source::Group(SourceEntry::CellDep) => Err(INDEX_OUT_OF_BOUND),
- Source::Group(SourceEntry::HeaderDep) => Err(INDEX_OUT_OF_BOUND),
- }
+ };
+ let addr = machine.registers()[A0].to_u64();
+ let size_addr = machine.registers()[A1].clone();
+ let size = machine.memory_mut().load64(&size_addr)?.to_u64();
+ let offset = machine.registers()[A2].to_u64();
+ let mut sc = self
+ .snapshot2_context
+ .lock()
+ .map_err(|e| VMError::Unexpected(e.to_string()))?;
+
+ let (wrote_size, full_size) =
+ match sc.store_bytes(machine, addr, &data_piece_id, offset, size) {
+ Ok(val) => val,
+ Err(VMError::External(m)) if m == "INDEX_OUT_OF_BOUND" => {
+ // This comes from TxData results in an out of bound error, to
+ // mimic current behavior, we would return INDEX_OUT_OF_BOUND error.
+ machine.set_register(A0, Mac::REG::from_u8(INDEX_OUT_OF_BOUND));
+ return Ok(());
+ }
+ Err(e) => return Err(e),
+ };
+ machine
+ .memory_mut()
+ .store64(&size_addr, &Mac::REG::from_u64(full_size))?;
+ machine.add_cycles_no_checking(transferred_byte_cycles(wrote_size))?;
+ machine.set_register(A0, Mac::REG::from_u8(SUCCESS));
+ Ok(())
}
fn load_data_as_code(&self, machine: &mut Mac) -> Result<(), VMError> {
@@ -88,75 +75,63 @@ impl LoadCellData {
let memory_size = machine.registers()[A1].to_u64();
let content_offset = machine.registers()[A2].to_u64();
let content_size = machine.registers()[A3].to_u64();
-
let index = machine.registers()[A4].to_u64();
- let source = Source::parse_from_u64(machine.registers()[A5].to_u64())?;
-
- let cell = self.fetch_cell(source, index as usize);
- if let Err(err) = cell {
- machine.set_register(A0, Mac::REG::from_u8(err));
- return Ok(());
- }
- let cell = cell.unwrap();
-
+ let source = machine.registers()[A5].to_u64();
+ let data_piece_id = match DataPieceId::try_from((source, index, 0)) {
+ Ok(id) => id,
+ Err(_) => {
+ machine.set_register(A0, Mac::REG::from_u8(INDEX_OUT_OF_BOUND));
+ return Ok(());
+ }
+ };
+ let mut sc = self
+ .snapshot2_context
+ .lock()
+ .map_err(|e| VMError::Unexpected(e.to_string()))?;
+ // We are using 0..u64::max_value() to fetch full cell, there is
+ // also no need to keep the full length value. Since cell's length
+ // is already full length.
+ let (cell, _) = match sc
+ .data_source()
+ .load_data(&data_piece_id, 0, u64::max_value())
+ {
+ Ok(val) => val,
+ Err(VMError::External(m)) if m == "INDEX_OUT_OF_BOUND" => {
+ // This comes from TxData results in an out of bound error, to
+ // mimic current behavior, we would return INDEX_OUT_OF_BOUND error.
+ machine.set_register(A0, Mac::REG::from_u8(INDEX_OUT_OF_BOUND));
+ return Ok(());
+ }
+ Err(e) => return Err(e),
+ };
let content_end = content_offset
.checked_add(content_size)
.ok_or(VMError::MemOutOfBound)?;
- if content_offset >= cell.data_bytes
- || content_end > cell.data_bytes
+ if content_offset >= cell.len() as u64
+ || content_end > cell.len() as u64
|| content_size > memory_size
{
machine.set_register(A0, Mac::REG::from_u8(SLICE_OUT_OF_BOUND));
return Ok(());
}
- let data = self
- .data_loader
- .load_cell_data(cell)
- .ok_or_else(|| {
- VMError::Unexpected(format!(
- "Unexpected load_cell_data failed {}",
- cell.out_point,
- ))
- })?
- .slice((content_offset as usize)..(content_end as usize));
machine.memory_mut().init_pages(
addr,
memory_size,
FLAG_EXECUTABLE | FLAG_FREEZED,
- Some(data),
+ Some(cell.slice((content_offset as usize)..(content_end as usize))),
0,
)?;
-
+ sc.track_pages(machine, addr, memory_size, &data_piece_id, content_offset)?;
machine.add_cycles_no_checking(transferred_byte_cycles(memory_size))?;
machine.set_register(A0, Mac::REG::from_u8(SUCCESS));
Ok(())
}
-
- fn load_data(&self, machine: &mut Mac) -> Result<(), VMError> {
- let index = machine.registers()[A3].to_u64();
- let source = Source::parse_from_u64(machine.registers()[A4].to_u64())?;
-
- let cell = self.fetch_cell(source, index as usize);
- if let Err(err) = cell {
- machine.set_register(A0, Mac::REG::from_u8(err));
- return Ok(());
- }
- let cell = cell.unwrap();
- let data = self.data_loader.load_cell_data(cell).ok_or_else(|| {
- VMError::Unexpected(format!(
- "Unexpected load_cell_data failed {}",
- cell.out_point,
- ))
- })?;
-
- let wrote_size = store_data(machine, &data)?;
- machine.add_cycles_no_checking(transferred_byte_cycles(wrote_size))?;
- machine.set_register(A0, Mac::REG::from_u8(SUCCESS));
- Ok(())
- }
}
-impl Syscalls for LoadCellData {
+impl Syscalls for LoadCellData
+where
+ DL: CellDataProvider + HeaderProvider + ExtensionProvider + Send + Sync + Clone + 'static,
+{
fn initialize(&mut self, _machine: &mut Mac) -> Result<(), VMError> {
Ok(())
}
diff --git a/script/src/syscalls/tests/vm_latest/syscalls_1.rs b/script/src/syscalls/tests/vm_latest/syscalls_1.rs
index 391320a556..5e67fd5346 100644
--- a/script/src/syscalls/tests/vm_latest/syscalls_1.rs
+++ b/script/src/syscalls/tests/vm_latest/syscalls_1.rs
@@ -14,14 +14,17 @@ use ckb_types::{
use ckb_vm::{
memory::{FLAG_DIRTY, FLAG_EXECUTABLE, FLAG_FREEZED, FLAG_WRITABLE},
registers::{A0, A1, A2, A3, A4, A5, A7},
+ snapshot2::{DataSource, Snapshot2, Snapshot2Context},
CoreMachine, Error as VMError, Memory, Syscalls, RISCV_PAGESIZE,
};
use proptest::{collection::size_range, prelude::*};
use std::collections::HashMap;
-use std::sync::Arc;
+use std::sync::{Arc, Mutex};
use super::SCRIPT_VERSION;
use crate::syscalls::{tests::utils::*, *};
+use crate::types::{ScriptGroup, ScriptGroupType};
+use crate::v2_types::TxData;
fn _test_load_cell_not_exist(data: &[u8]) -> Result<(), TestCaseError> {
let mut machine = SCRIPT_VERSION.init_core_machine_without_limit();
@@ -1453,17 +1456,26 @@ fn _test_load_cell_data_as_code(
let output = build_cell_meta(100, data.clone());
let input_cell = build_cell_meta(100, data.clone());
- let outputs = Arc::new(vec![output]);
- let group_inputs = Arc::new(vec![0]);
- let group_outputs = Arc::new(vec![0]);
let data_loader = new_mock_data_loader();
let rtx = Arc::new(ResolvedTransaction {
- transaction: TransactionBuilder::default().build(),
+ transaction: TransactionBuilder::default()
+ .output_data(data.pack())
+ .build(),
resolved_cell_deps: vec![dep_cell],
resolved_inputs: vec![input_cell],
resolved_dep_groups: vec![],
});
- let mut load_code = LoadCellData::new(data_loader, rtx, outputs, group_inputs, group_outputs);
+ let mut load_code = LoadCellData::new(Arc::new(Mutex::new(Snapshot2Context::new(TxData {
+ rtx: rtx,
+ data_loader: data_loader,
+ program: Bytes::new(),
+ script_group: Arc::new(ScriptGroup {
+ script: Default::default(),
+ group_type: ScriptGroupType::Lock,
+ input_indices: vec![0],
+ output_indices: vec![0],
+ }),
+ }))));
prop_assert!(machine.memory_mut().store_byte(addr, addr_size, 1).is_ok());
@@ -1474,7 +1486,7 @@ fn _test_load_cell_data_as_code(
} else {
prop_assert_eq!(machine.registers()[A0], u64::from(SUCCESS));
- let flags = FLAG_EXECUTABLE | FLAG_FREEZED | FLAG_DIRTY;
+ let flags = FLAG_EXECUTABLE | FLAG_FREEZED;
prop_assert_eq!(
machine
.memory_mut()
@@ -1517,19 +1529,27 @@ fn _test_load_cell_data(
let dep_cell = build_cell_meta(10000, data.clone());
let output = build_cell_meta(100, data.clone());
let input_cell = build_cell_meta(100, data.clone());
-
- let outputs = Arc::new(vec![output]);
- let group_inputs = Arc::new(vec![0]);
- let group_outputs = Arc::new(vec![0]);
let data_loader = new_mock_data_loader();
let rtx = Arc::new(ResolvedTransaction {
- transaction: TransactionBuilder::default().build(),
+ transaction: TransactionBuilder::default()
+ .output_data(data.pack())
+ .build(),
resolved_cell_deps: vec![dep_cell],
resolved_inputs: vec![input_cell],
resolved_dep_groups: vec![],
});
- let mut load_code = LoadCellData::new(data_loader, rtx, outputs, group_inputs, group_outputs);
+ let mut load_code = LoadCellData::new(Arc::new(Mutex::new(Snapshot2Context::new(TxData {
+ rtx: rtx,
+ data_loader: data_loader,
+ program: Bytes::new(),
+ script_group: Arc::new(ScriptGroup {
+ script: Default::default(),
+ group_type: ScriptGroupType::Lock,
+ input_indices: vec![0],
+ output_indices: vec![0],
+ }),
+ }))));
prop_assert!(load_code.ecall(&mut machine).is_ok());
@@ -1537,8 +1557,11 @@ fn _test_load_cell_data(
prop_assert_eq!(machine.registers()[A0], u64::from(code));
} else {
prop_assert_eq!(machine.registers()[A0], u64::from(SUCCESS));
-
- let flags = FLAG_WRITABLE | FLAG_DIRTY;
+ let flags = if data.len() < RISCV_PAGESIZE {
+ FLAG_WRITABLE | FLAG_DIRTY
+ } else {
+ FLAG_WRITABLE
+ };
prop_assert_eq!(
machine
.memory_mut()
@@ -1618,9 +1641,6 @@ fn test_load_overflowed_cell_data_as_code() {
let dep_cell = build_cell_meta(10000, dep_cell_data);
let data_loader = new_mock_data_loader();
- let outputs = Arc::new(vec![]);
- let group_inputs = Arc::new(vec![]);
- let group_outputs = Arc::new(vec![]);
let rtx = Arc::new(ResolvedTransaction {
transaction: TransactionBuilder::default().build(),
@@ -1629,7 +1649,17 @@ fn test_load_overflowed_cell_data_as_code() {
resolved_dep_groups: vec![],
});
- let mut load_code = LoadCellData::new(data_loader, rtx, outputs, group_inputs, group_outputs);
+ let mut load_code = LoadCellData::new(Arc::new(Mutex::new(Snapshot2Context::new(TxData {
+ rtx: rtx,
+ data_loader: data_loader,
+ program: Bytes::new(),
+ script_group: Arc::new(ScriptGroup {
+ script: Default::default(),
+ group_type: ScriptGroupType::Lock,
+ input_indices: Default::default(),
+ output_indices: Default::default(),
+ }),
+ }))));
assert!(machine.memory_mut().store_byte(addr, addr_size, 1).is_ok());
@@ -1637,7 +1667,61 @@ fn test_load_overflowed_cell_data_as_code() {
assert_eq!(result.unwrap_err(), VMError::MemOutOfBound);
}
-fn _test_load_cell_data_on_freezed_memory(as_code: bool, data: &[u8]) -> Result<(), TestCaseError> {
+fn _test_load_cell_data_on_freezed_memory(data: &[u8]) -> Result<(), TestCaseError> {
+ let mut machine = SCRIPT_VERSION.init_core_machine_without_limit();
+ let addr = 8192;
+ let addr_size = 4096;
+ let size_addr = 100;
+
+ prop_assert!(machine
+ .memory_mut()
+ .store64(&size_addr, &(data.len() as u64))
+ .is_ok());
+ prop_assert!(machine
+ .memory_mut()
+ .init_pages(addr, addr_size, FLAG_EXECUTABLE | FLAG_FREEZED, None, 0)
+ .is_ok());
+
+ machine.set_register(A0, addr); // addr
+ machine.set_register(A1, size_addr); // size
+ machine.set_register(A2, 0); // content offset
+ machine.set_register(A3, 0); //index
+ machine.set_register(A4, u64::from(Source::Transaction(SourceEntry::CellDep))); //source
+ machine.set_register(A7, LOAD_CELL_DATA_SYSCALL_NUMBER); // syscall number
+
+ let dep_cell_data = Bytes::from(data.to_owned());
+ let dep_cell = build_cell_meta(10000, dep_cell_data);
+
+ let data_loader = new_mock_data_loader();
+
+ let rtx = Arc::new(ResolvedTransaction {
+ transaction: TransactionBuilder::default().build(),
+ resolved_cell_deps: vec![dep_cell],
+ resolved_inputs: vec![],
+ resolved_dep_groups: vec![],
+ });
+
+ let mut load_code = LoadCellData::new(Arc::new(Mutex::new(Snapshot2Context::new(TxData {
+ rtx: rtx,
+ data_loader: data_loader,
+ program: Bytes::new(),
+ script_group: Arc::new(ScriptGroup {
+ script: Default::default(),
+ group_type: ScriptGroupType::Lock,
+ input_indices: Default::default(),
+ output_indices: Default::default(),
+ }),
+ }))));
+
+ prop_assert!(load_code.ecall(&mut machine).is_err());
+
+ for i in addr..addr + addr_size {
+ assert_eq!(machine.memory_mut().load8(&i), Ok(0));
+ }
+ Ok(())
+}
+
+fn _test_load_cell_data_as_code_on_freezed_memory(data: &[u8]) -> Result<(), TestCaseError> {
let mut machine = SCRIPT_VERSION.init_core_machine_without_limit();
let addr = 8192;
let addr_size = 4096;
@@ -1653,20 +1737,12 @@ fn _test_load_cell_data_on_freezed_memory(as_code: bool, data: &[u8]) -> Result<
machine.set_register(A3, data.len() as u64); // content size
machine.set_register(A4, 0); //index
machine.set_register(A5, u64::from(Source::Transaction(SourceEntry::CellDep))); //source
- let syscall = if as_code {
- LOAD_CELL_DATA_AS_CODE_SYSCALL_NUMBER
- } else {
- LOAD_CELL_DATA_SYSCALL_NUMBER
- };
- machine.set_register(A7, syscall); // syscall number
+ machine.set_register(A7, LOAD_CELL_DATA_AS_CODE_SYSCALL_NUMBER); // syscall number
let dep_cell_data = Bytes::from(data.to_owned());
let dep_cell = build_cell_meta(10000, dep_cell_data);
let data_loader = new_mock_data_loader();
- let outputs = Arc::new(vec![]);
- let group_inputs = Arc::new(vec![]);
- let group_outputs = Arc::new(vec![]);
let rtx = Arc::new(ResolvedTransaction {
transaction: TransactionBuilder::default().build(),
@@ -1675,7 +1751,17 @@ fn _test_load_cell_data_on_freezed_memory(as_code: bool, data: &[u8]) -> Result<
resolved_dep_groups: vec![],
});
- let mut load_code = LoadCellData::new(data_loader, rtx, outputs, group_inputs, group_outputs);
+ let mut load_code = LoadCellData::new(Arc::new(Mutex::new(Snapshot2Context::new(TxData {
+ rtx: rtx,
+ data_loader: data_loader,
+ program: Bytes::new(),
+ script_group: Arc::new(ScriptGroup {
+ script: Default::default(),
+ group_type: ScriptGroupType::Lock,
+ input_indices: Default::default(),
+ output_indices: Default::default(),
+ }),
+ }))));
prop_assert!(load_code.ecall(&mut machine).is_err());
@@ -1691,12 +1777,12 @@ proptest! {
})]
#[test]
fn test_load_code_on_freezed_memory(ref data in any_with::>(size_range(4096).lift())) {
- _test_load_cell_data_on_freezed_memory(true, data)?;
+ _test_load_cell_data_as_code_on_freezed_memory(data)?;
}
#[test]
fn test_load_data_on_freezed_memory(ref data in any_with::>(size_range(4096).lift())) {
- _test_load_cell_data_on_freezed_memory(false, data)?;
+ _test_load_cell_data_on_freezed_memory(data)?;
}
}
@@ -1718,9 +1804,6 @@ fn test_load_code_unaligned_error() {
let dep_cell = build_cell_meta(10000, dep_cell_data);
let data_loader = new_mock_data_loader();
- let outputs = Arc::new(vec![]);
- let group_inputs = Arc::new(vec![]);
- let group_outputs = Arc::new(vec![]);
let rtx = Arc::new(ResolvedTransaction {
transaction: TransactionBuilder::default().build(),
@@ -1729,7 +1812,17 @@ fn test_load_code_unaligned_error() {
resolved_dep_groups: vec![],
});
- let mut load_code = LoadCellData::new(data_loader, rtx, outputs, group_inputs, group_outputs);
+ let mut load_code = LoadCellData::new(Arc::new(Mutex::new(Snapshot2Context::new(TxData {
+ rtx: rtx,
+ data_loader: data_loader,
+ program: Bytes::new(),
+ script_group: Arc::new(ScriptGroup {
+ script: Default::default(),
+ group_type: ScriptGroupType::Lock,
+ input_indices: Default::default(),
+ output_indices: Default::default(),
+ }),
+ }))));
assert!(machine.memory_mut().store_byte(addr, addr_size, 1).is_ok());
@@ -1759,9 +1852,6 @@ fn test_load_code_slice_out_of_bound_error() {
let dep_cell = build_cell_meta(10000, dep_cell_data);
let data_loader = new_mock_data_loader();
- let outputs = Arc::new(vec![]);
- let group_inputs = Arc::new(vec![]);
- let group_outputs = Arc::new(vec![]);
let rtx = Arc::new(ResolvedTransaction {
transaction: TransactionBuilder::default().build(),
@@ -1770,7 +1860,17 @@ fn test_load_code_slice_out_of_bound_error() {
resolved_dep_groups: vec![],
});
- let mut load_code = LoadCellData::new(data_loader, rtx, outputs, group_inputs, group_outputs);
+ let mut load_code = LoadCellData::new(Arc::new(Mutex::new(Snapshot2Context::new(TxData {
+ rtx: rtx,
+ data_loader: data_loader,
+ program: Bytes::new(),
+ script_group: Arc::new(ScriptGroup {
+ script: Default::default(),
+ group_type: ScriptGroupType::Lock,
+ input_indices: Default::default(),
+ output_indices: Default::default(),
+ }),
+ }))));
assert!(machine.memory_mut().store_byte(addr, addr_size, 1).is_ok());
@@ -1803,9 +1903,6 @@ fn test_load_code_not_enough_space_error() {
let dep_cell = build_cell_meta(10000, dep_cell_data);
let data_loader = new_mock_data_loader();
- let outputs = Arc::new(vec![]);
- let group_inputs = Arc::new(vec![]);
- let group_outputs = Arc::new(vec![]);
let rtx = Arc::new(ResolvedTransaction {
transaction: TransactionBuilder::default().build(),
@@ -1814,7 +1911,17 @@ fn test_load_code_not_enough_space_error() {
resolved_dep_groups: vec![],
});
- let mut load_code = LoadCellData::new(data_loader, rtx, outputs, group_inputs, group_outputs);
+ let mut load_code = LoadCellData::new(Arc::new(Mutex::new(Snapshot2Context::new(TxData {
+ rtx: rtx,
+ data_loader: data_loader,
+ program: Bytes::new(),
+ script_group: Arc::new(ScriptGroup {
+ script: Default::default(),
+ group_type: ScriptGroupType::Lock,
+ input_indices: Default::default(),
+ output_indices: Default::default(),
+ }),
+ }))));
assert!(machine.memory_mut().store_byte(addr, addr_size, 1).is_ok());
diff --git a/script/src/v2_syscalls.rs b/script/src/v2_syscalls.rs
index 087ac72e50..7ca9a0425c 100644
--- a/script/src/v2_syscalls.rs
+++ b/script/src/v2_syscalls.rs
@@ -53,127 +53,6 @@ where
*self.base_cycles.lock().expect("lock") = base_cycles;
}
- // Reimplementation of load_cell_data but keep tracks of pages that are copied from
- // surrounding transaction data. Those pages do not need to be added to snapshots.
- fn load_cell_data(&mut self, machine: &mut Mac) -> Result<(), Error> {
- let index = machine.registers()[A3].to_u64();
- let source = machine.registers()[A4].to_u64();
-
- let data_piece_id = match DataPieceId::try_from((source, index, 0)) {
- Ok(id) => id,
- Err(e) => {
- // Current implementation would throw an error immediately
- // for some source values, but return INDEX_OUT_OF_BOUND error
- // for other values. Here for simplicity, we would return
- // INDEX_OUT_OF_BOUND error in all cases. But the code might
- // differ to mimic current on-chain behavior
- println!("DataPieceId parsing error: {:?}", e);
- machine.set_register(A0, Mac::REG::from_u8(INDEX_OUT_OF_BOUND));
- return Ok(());
- }
- };
-
- let addr = machine.registers()[A0].to_u64();
- let size_addr = machine.registers()[A1].clone();
- let size = machine.memory_mut().load64(&size_addr)?.to_u64();
- let offset = machine.registers()[A2].to_u64();
-
- let mut sc = self.snapshot2_context().lock().expect("lock");
- let (wrote_size, full_size) =
- match sc.store_bytes(machine, addr, &data_piece_id, offset, size) {
- Ok(val) => val,
- Err(Error::External(m)) if m == "INDEX_OUT_OF_BOUND" => {
- // This comes from TxData results in an out of bound error, to
- // mimic current behavior, we would return INDEX_OUT_OF_BOUND error.
- machine.set_register(A0, Mac::REG::from_u8(INDEX_OUT_OF_BOUND));
- return Ok(());
- }
- Err(e) => return Err(e),
- };
-
- machine
- .memory_mut()
- .store64(&size_addr, &Mac::REG::from_u64(full_size))?;
- machine.add_cycles_no_checking(transferred_byte_cycles(wrote_size))?;
- machine.set_register(A0, Mac::REG::from_u8(SUCCESS));
- Ok(())
- }
-
- // Reimplementation of load_cell_data_as_code but keep tracks of pages that are copied from
- // surrounding transaction data. Those pages do not need to be added to snapshots.
- //
- // Different from load_cell_data, this method showcases advanced usage of Snapshot2, where
- // one manually does the actual memory copying, then calls track_pages method to setup metadata
- // used by Snapshot2. It does not rely on higher level methods provided by Snapshot2.
- fn load_cell_data_as_code(
- &mut self,
- machine: &mut Mac,
- ) -> Result<(), Error> {
- let addr = machine.registers()[A0].to_u64();
- let memory_size = machine.registers()[A1].to_u64();
- let content_offset = machine.registers()[A2].to_u64();
- let content_size = machine.registers()[A3].to_u64();
-
- let index = machine.registers()[A4].to_u64();
- let source = machine.registers()[A5].to_u64();
-
- let data_piece_id = match DataPieceId::try_from((source, index, 0)) {
- Ok(id) => id,
- Err(e) => {
- // Current implementation would throw an error immediately
- // for some source values, but return INDEX_OUT_OF_BOUND error
- // for other values. Here for simplicity, we would return
- // INDEX_OUT_OF_BOUND error in all cases. But the code might
- // differ to mimic current on-chain behavior
- println!("DataPieceId parsing error: {:?}", e);
- machine.set_register(A0, Mac::REG::from_u8(INDEX_OUT_OF_BOUND));
- return Ok(());
- }
- };
-
- let mut sc = self.snapshot2_context().lock().expect("lock");
- // We are using 0..u64::max_value() to fetch full cell, there is
- // also no need to keep the full length value. Since cell's length
- // is already full length.
- let (cell, _) = match sc
- .data_source()
- .load_data(&data_piece_id, 0, u64::max_value())
- {
- Ok(val) => val,
- Err(Error::External(m)) if m == "INDEX_OUT_OF_BOUND" => {
- // This comes from TxData results in an out of bound error, to
- // mimic current behavior, we would return INDEX_OUT_OF_BOUND error.
- machine.set_register(A0, Mac::REG::from_u8(INDEX_OUT_OF_BOUND));
- return Ok(());
- }
- Err(e) => return Err(e),
- };
-
- let content_end = content_offset
- .checked_add(content_size)
- .ok_or(Error::MemOutOfBound)?;
- if content_offset >= cell.len() as u64
- || content_end > cell.len() as u64
- || content_size > memory_size
- {
- machine.set_register(A0, Mac::REG::from_u8(SLICE_OUT_OF_BOUND));
- return Ok(());
- }
-
- machine.memory_mut().init_pages(
- addr,
- memory_size,
- FLAG_EXECUTABLE | FLAG_FREEZED,
- Some(cell.slice((content_offset as usize)..(content_end as usize))),
- 0,
- )?;
- sc.track_pages(machine, addr, memory_size, &data_piece_id, content_offset)?;
-
- machine.add_cycles_no_checking(transferred_byte_cycles(memory_size))?;
- machine.set_register(A0, Mac::REG::from_u8(SUCCESS));
- Ok(())
- }
-
// Reimplementing debug syscall for printing debug messages
fn debug(&mut self, machine: &mut Mac) -> Result<(), Error> {
let mut addr = machine.registers()[A0].to_u64();
@@ -211,8 +90,6 @@ where
fn ecall(&mut self, machine: &mut Mac) -> Result {
let code = machine.registers()[A7].to_u64();
match code {
- 2091 => self.load_cell_data_as_code(machine),
- 2092 => self.load_cell_data(machine),
2177 => self.debug(machine),
_ => return Ok(false),
}?;
diff --git a/script/src/verify.rs b/script/src/verify.rs
index 5f014cd617..7341316fa5 100644
--- a/script/src/verify.rs
+++ b/script/src/verify.rs
@@ -202,18 +202,8 @@ where
}
/// Build syscall: load_cell_data
- pub fn build_load_cell_data(
- &self,
- group_inputs: Indices,
- group_outputs: Indices,
- ) -> LoadCellData {
- LoadCellData::new(
- self.data_loader.clone(),
- Arc::clone(&self.rtx),
- Arc::clone(&self.outputs),
- group_inputs,
- group_outputs,
- )
+ pub fn build_load_cell_data(&self) -> LoadCellData {
+ LoadCellData::new(self.snapshot2_context.clone())
}
///Build syscall: load_input
@@ -321,10 +311,7 @@ where
Arc::clone(&script_group_output_indices),
)),
Box::new(self.build_load_script(script_group.script.clone())),
- Box::new(self.build_load_cell_data(
- Arc::clone(&script_group_input_indices),
- Arc::clone(&script_group_output_indices),
- )),
+ Box::new(self.build_load_cell_data()),
Box::new(Debugger::new(
current_script_hash,
Arc::clone(&self.debug_printer),