Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/node/snapshot_serdes.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ namespace ccf
auto store_snapshot_size =
sizeof(ccf::kv::SerialisedEntryHeader) + tx_hdr.size;

if (tx_hdr.size == 0)
{
throw std::logic_error("Snapshot transaction size should not be zero");
}

auto receipt_data = data + store_snapshot_size;
auto receipt_size = size - store_snapshot_size;

Expand All @@ -58,6 +63,20 @@ namespace ccf
throw std::logic_error("No receipt included in snapshot");
}

LOG_INFO_FMT("Deserialising snapshot receipt (size: {}).", receipt_size);
constexpr size_t max_printed_size = 1024;
if (receipt_size > max_printed_size)
{
LOG_INFO_FMT(
"Receipt size ({}) exceeds max printed size ({}), only printing "
"first {} bytes",
receipt_size,
max_printed_size,
max_printed_size);
}
auto printed_size = std::min<size_t>(receipt_size, max_printed_size);
LOG_INFO_FMT("{}", ds::to_hex(receipt_data, receipt_data + printed_size));

auto j = nlohmann::json::parse(receipt_data, receipt_data + receipt_size);
auto receipt_p = j.get<ReceiptPtr>();
auto receipt = std::dynamic_pointer_cast<ccf::ProofReceipt>(receipt_p);
Expand Down
35 changes: 35 additions & 0 deletions tests/e2e_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,40 @@ def test_empty_snapshot(network, args):
)


def test_nulled_snapshot(network, args):

with tempfile.TemporaryDirectory() as snapshots_dir:
LOG.debug(f"Using {snapshots_dir} as snapshots directory")

snapshot_name = "snapshot_1000_1500.committed"

with open(
os.path.join(snapshots_dir, snapshot_name), "wb+"
) as temp_empty_snapshot:

LOG.debug(f"Created empty snapshot {temp_empty_snapshot.name}")
temp_empty_snapshot.write(b"\x00" * 64)

LOG.info(
"Attempt to join a node using the corrupted snapshot copy (should fail)"
)
new_node = network.create_node("local://localhost")
failed = False
try:
network.join_node(
new_node,
args.package,
args,
snapshots_dir=snapshots_dir,
)
except Exception as e:
failed = True
LOG.info(f"Node failed to join as expected: {e}")

# (Existing assertion logic retained)
assert failed, "Node should not have joined successfully"


def split_all_ledger_files_in_dir(input_dir, output_dir):
# A ledger file can only be split at a seqno that contains a signature
# (so that all files end on a signature that verifies their integrity).
Expand Down Expand Up @@ -493,6 +527,7 @@ def run_file_operations(args):
test_large_snapshot(network, args)
test_snapshot_access(network, args)
test_empty_snapshot(network, args)
test_nulled_snapshot(network, args)

primary, _ = network.find_primary()
# Scoped transactions are not handled by historical range queries
Expand Down