Part 4: Using the entire slot
In some cases, you may want to retrieve the entire contents of a slot. For example, it can be convenient to get the entire slot because it has a fixed size, while the data in the slot may be smaller and padded to fit the slot.
Fetching and storing the full slot
Retrieving the full slot is similar to retrieving any data from the slot. In this case, you change the kernel to retrieve data of the exact size of the slot.
-
Update the
run
function in thelib/rs
file to this code:pub fn run<R: Runtime>(
host: &mut R,
param: &RollupDalParameters,
slot_index: u8,
) -> Result<(), RuntimeError> {
// Reading one message from the shared inbox is always safe,
// because the shared inbox contains at least 3 messages per
// Tezos block.
let sol = host.read_input()?.unwrap();
let target_level = sol.level as usize - param.attestation_lag as usize;
let mut buffer = vec![0u8; param.slot_size as usize];
let bytes_read = host.reveal_dal_page(target_level as i32, slot_index, 0, &mut buffer)?;
if bytes_read == 0 {
debug_msg!(
host,
"No attested slot at index {} for level {}\n",
slot_index,
target_level
);
return Ok(());
}
debug_msg!(
host,
"Attested slot at index {} for level {}\n",
slot_index,
target_level
);
let num_pages = param.slot_size / param.page_size;
for page_index in 1..num_pages {
let _result = host.reveal_dal_page(
target_level as i32,
slot_index,
page_index.try_into().unwrap(),
&mut buffer[page_index as usize * (param.page_size as usize)
..(page_index as usize + 1) * (param.page_size as usize)],
);
}
let hash = blake2b::digest(&buffer, 32).unwrap();
let key = hex::encode(hash);
let path = OwnedPath::try_from(format!("/{}", key)).unwrap();
debug_msg!(host, "Saving slot under `{}'\n", path);
let () = host.store_write_all(&path, &buffer)?;
Ok(())
}Now the
run
function works like this:- It allocates a buffer of the size of a slot, not a size of a page.
- It tries to fetch the contents of the first page.
If 0 bytes are written by
reveal_dal_page
, the targeted slot has not been attested for this block. - If the targeted slot has been attested, the function reads as many pages as necessary to get the full slot data.
- It stores the data in the durable storage, using the Blake2B hash (encoded in hexadecimal) as its key.
-
Add these
use
statements to the beginning of the file:use tezos_crypto_rs::blake2b;
use tezos_smart_rollup::storage::path::OwnedPath;These dependencies use
tezos_crypto_rs
for hashing, andhex
for encoding. -
Add the matching dependencies to the
Cargo.toml
file:tezos_crypto_rs = { version = "0.5.2", default-features = false }
hex = "0.4.3"Adding
default-features = false
fortezos_crypto_rs
is necessary for the crate to be compatible with Smart Rollups. -
Deploy the Smart Rollup again, publish a file as you did in the previous section, and wait for enough levels to pass. The Smart Rollup log shows the hash of the data, as in this example:
RollupDalParameters { number_of_slots: 32, attestation_lag: 4, slot_size: 65536, page_size: 4096 }
Attested slot at index 10 for level 15482
Saving slot under `/6a578d1e6746d29243ff81923bcea6375e9344d719ca118e14cd9f3d3b00cd96'
See you in the next level -
Get the data from the slot by passing the hash, as in this example:
hash=6a578d1e6746d29243ff81923bcea6375e9344d719ca118e14cd9f3d3b00cd96
curl "http://localhost:8932/global/block/head/durable/wasm_2_0_0/value?key=/${hash}" \
-H 'Content-Type: application/octet-stream' \
-o slot.bin -
Inspect the contents of the slot by running this command:
hexdump -C slot.bin
For example, if you uploaded a file that contained the text "Hi! This is a message to go on the DAL." the slot might look like this:
00000000 22 34 38 36 39 32 31 32 30 35 34 36 38 36 39 37 |"486921205468697|
00000010 33 32 30 36 39 37 33 32 30 36 31 32 30 36 64 36 |32069732061206d6|
00000020 35 37 33 37 33 36 31 36 37 36 35 32 30 37 34 36 |5737361676520746|
00000030 66 32 30 36 37 36 66 32 30 36 66 36 65 32 30 37 |f20676f206f6e207|
00000040 34 36 38 36 35 32 30 34 34 34 31 34 63 32 65 30 |468652044414c2e0|
00000050 61 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 |a000000000000000|
00000060 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 |0000000000000000|
*
00020000 30 22 0a |0".|
00020003
diff
won't workYou cannot use diff
to ensure that the file you originally published and the one that you downloaded from the rollup node are equal.
Indeed, they are not: because the size of a slot is fixed, the DAL node pads the value it receives from POST /slot
in order to ensure that it has the correct size.
Next steps
Now you know how to send files to the DAL and use a Smart Rollup to store the data.
From there, the sky's the limit. You can implement other features implemented, such as having the file publishers pay for the storage they are using in Layer 2 (by allowing them to deposit tez to the Smart Rollup and sign the files they publish). You could also build a frontend to visualize the files published in the archive. Or, you could deal with the fact that for now, it is not possible for a consumer of the file to know its original size. You could fix that by modifying the script to prefix the file with its size.