decodeBlob method
Decode (reconstruct) a blob from primary slivers via Rust FFI.
Uses walrus-core's RS2 decoder — the same decoder used by the
Walrus network for canonical reconstruction. This is dramatically
faster than any pure-Dart erasure coding implementation.
nShards: number of shards in the committee.
blobSize: the original unencoded blob length in bytes.
slivers: list of (index, data) pairs — the shard index and raw
primary sliver bytes for each available sliver. Minimum required
is primarySymbols (from encodingParams).
Returns the reconstructed original blob data.
Implementation
Uint8List decodeBlob({
required int nShards,
required int blobSize,
required List<({int index, Uint8List data})> slivers,
}) {
if (slivers.isEmpty) {
throw WalrusFfiException('decodeBlob: no slivers provided');
}
final sliverSize = slivers.first.data.length;
final sliverCount = slivers.length;
// Allocate flat buffers for all sliver data + indices.
final totalSliverBytes = sliverCount * sliverSize;
final sliverDataPtr = calloc<Uint8>(
totalSliverBytes == 0 ? 1 : totalSliverBytes,
);
final sliverIndicesPtr = calloc<Uint16>(sliverCount);
final outBlobPtr = calloc<Uint8>(blobSize == 0 ? 1 : blobSize);
final outBlobLen = calloc<Uint64>(1);
try {
// Copy sliver data into the flat buffer.
final flatView = sliverDataPtr.asTypedList(totalSliverBytes);
final indicesView = sliverIndicesPtr.asTypedList(sliverCount);
for (var i = 0; i < sliverCount; i++) {
flatView.setRange(
i * sliverSize,
(i + 1) * sliverSize,
slivers[i].data,
);
indicesView[i] = slivers[i].index;
}
final ret = _decodeBlob(
nShards,
blobSize,
sliverDataPtr,
sliverIndicesPtr,
sliverCount,
sliverSize,
outBlobPtr,
outBlobLen,
);
if (ret != 0) {
throw WalrusFfiException(
'walrus_decode_blob failed with code $ret '
'(slivers=$sliverCount, sliverSize=$sliverSize, blobSize=$blobSize)',
);
}
final decodedLen = outBlobLen.value;
return Uint8List.fromList(outBlobPtr.asTypedList(decodedLen));
} finally {
calloc.free(sliverDataPtr);
calloc.free(sliverIndicesPtr);
calloc.free(outBlobPtr);
calloc.free(outBlobLen);
}
}