feat: Rebrand Polkadot/Substrate references to PezkuwiChain
This commit systematically rebrands various references from Parity Technologies' Polkadot/Substrate ecosystem to PezkuwiChain within the kurdistan-sdk. Key changes include: - Updated external repository URLs (zombienet-sdk, parity-db, parity-scale-codec, wasm-instrument) to point to pezkuwichain forks. - Modified internal documentation and code comments to reflect PezkuwiChain naming and structure. - Replaced direct references to with or specific paths within the for XCM, Pezkuwi, and other modules. - Cleaned up deprecated issue and PR references in various and files, particularly in and modules. - Adjusted image and logo URLs in documentation to point to PezkuwiChain assets. - Removed or rephrased comments related to external Polkadot/Substrate PRs and issues. This is a significant step towards fully customizing the SDK for the PezkuwiChain ecosystem.
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "pezsp-maybe-compressed-blob"
|
||||
version = "11.0.0"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
license = "Apache-2.0"
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
description = "Handling of blobs, usually Wasm code, which may be compressed"
|
||||
documentation = "https://docs.rs/pezsp-maybe-compressed-blob"
|
||||
readme = "README.md"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
thiserror = { workspace = true }
|
||||
zstd = { workspace = true }
|
||||
@@ -0,0 +1,3 @@
|
||||
Handling of blobs, typically validation code, which may be compressed.
|
||||
|
||||
License: Apache-2.0
|
||||
@@ -0,0 +1,181 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Handling of blobs that may be compressed, based on an 8-byte magic identifier
|
||||
//! at the head.
|
||||
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
io::{Read, Write},
|
||||
};
|
||||
|
||||
// An arbitrary prefix, that indicates a blob beginning with should be decompressed with
|
||||
// Zstd compression.
|
||||
//
|
||||
// This differs from the WASM magic bytes, so real WASM blobs will not have this prefix.
|
||||
const ZSTD_PREFIX: [u8; 8] = [82, 188, 83, 118, 70, 219, 142, 5];
|
||||
|
||||
/// A recommendation for the bomb limit for code blobs.
|
||||
///
|
||||
/// This may be adjusted upwards in the future, but is set much higher than the
|
||||
/// expected maximum code size. When adjusting upwards, nodes should be updated
|
||||
/// before performing a runtime upgrade to a blob with larger compressed size.
|
||||
pub const CODE_BLOB_BOMB_LIMIT: usize = 50 * 1024 * 1024;
|
||||
|
||||
/// A possible bomb was encountered.
|
||||
#[derive(Debug, Clone, PartialEq, thiserror::Error)]
|
||||
pub enum Error {
|
||||
/// Decoded size was too large, and the code payload may be a bomb.
|
||||
#[error("Possible compression bomb encountered")]
|
||||
PossibleBomb,
|
||||
/// The compressed value had an invalid format.
|
||||
#[error("Blob had invalid format")]
|
||||
Invalid,
|
||||
}
|
||||
|
||||
fn read_from_decoder(
|
||||
decoder: impl Read,
|
||||
blob_len: usize,
|
||||
bomb_limit: usize,
|
||||
) -> Result<Vec<u8>, Error> {
|
||||
let mut decoder = decoder.take((bomb_limit + 1) as u64);
|
||||
|
||||
let mut buf = Vec::with_capacity(blob_len);
|
||||
decoder.read_to_end(&mut buf).map_err(|_| Error::Invalid)?;
|
||||
|
||||
if buf.len() <= bomb_limit {
|
||||
Ok(buf)
|
||||
} else {
|
||||
Err(Error::PossibleBomb)
|
||||
}
|
||||
}
|
||||
|
||||
fn decompress_zstd(blob: &[u8], bomb_limit: usize) -> Result<Vec<u8>, Error> {
|
||||
let decoder = zstd::Decoder::new(blob).map_err(|_| Error::Invalid)?;
|
||||
|
||||
read_from_decoder(decoder, blob.len(), bomb_limit)
|
||||
}
|
||||
|
||||
/// Decode a blob, if it indicates that it is compressed. Provide a `bomb_limit`, which
|
||||
/// is the limit of bytes which should be decompressed from the blob.
|
||||
pub fn decompress(blob: &[u8], bomb_limit: usize) -> Result<Cow<'_, [u8]>, Error> {
|
||||
if blob.starts_with(&ZSTD_PREFIX) {
|
||||
decompress_zstd(&blob[ZSTD_PREFIX.len()..], bomb_limit).map(Into::into)
|
||||
} else {
|
||||
Ok(blob.into())
|
||||
}
|
||||
}
|
||||
|
||||
/// Weakly compress a blob who's size is limited by `bomb_limit`.
|
||||
///
|
||||
/// If the blob's size is over the bomb limit, this will not compress the blob,
|
||||
/// as the decoder will not be able to be able to differentiate it from a compression bomb.
|
||||
pub fn compress_weakly(blob: &[u8], bomb_limit: usize) -> Option<Vec<u8>> {
|
||||
compress_with_level(blob, bomb_limit, 3)
|
||||
}
|
||||
|
||||
/// Strongly compress a blob who's size is limited by `bomb_limit`.
|
||||
///
|
||||
/// If the blob's size is over the bomb limit, this will not compress the blob, as the decoder will
|
||||
/// not be able to be able to differentiate it from a compression bomb.
|
||||
pub fn compress_strongly(blob: &[u8], bomb_limit: usize) -> Option<Vec<u8>> {
|
||||
compress_with_level(blob, bomb_limit, 22)
|
||||
}
|
||||
|
||||
/// Compress a blob who's size is limited by `bomb_limit`.
|
||||
///
|
||||
/// If the blob's size is over the bomb limit, this will not compress the blob, as the decoder will
|
||||
/// not be able to be able to differentiate it from a compression bomb.
|
||||
#[deprecated(
|
||||
note = "Will be removed after June 2026. Use compress_strongly, compress_weakly or compress_with_level instead"
|
||||
)]
|
||||
pub fn compress(blob: &[u8], bomb_limit: usize) -> Option<Vec<u8>> {
|
||||
compress_with_level(blob, bomb_limit, 3)
|
||||
}
|
||||
|
||||
/// Compress a blob who's size is limited by `bomb_limit` with adjustable compression level.
|
||||
///
|
||||
/// The levels are passed through to `zstd` and can be in range [1, 22] (weakest to strongest).
|
||||
///
|
||||
/// If the blob's size is over the bomb limit, this will not compress the blob, as the decoder will
|
||||
/// not be able to be able to differentiate it from a compression bomb.
|
||||
fn compress_with_level(blob: &[u8], bomb_limit: usize, level: i32) -> Option<Vec<u8>> {
|
||||
if blob.len() > bomb_limit {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut buf = ZSTD_PREFIX.to_vec();
|
||||
|
||||
{
|
||||
let mut v = zstd::Encoder::new(&mut buf, level).ok()?.auto_finish();
|
||||
v.write_all(blob).ok()?;
|
||||
}
|
||||
|
||||
Some(buf)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const BOMB_LIMIT: usize = 10;
|
||||
|
||||
#[test]
|
||||
fn refuse_to_encode_over_limit() {
|
||||
let mut v = vec![0; BOMB_LIMIT + 1];
|
||||
assert!(compress_weakly(&v, BOMB_LIMIT).is_none());
|
||||
assert!(compress_strongly(&v, BOMB_LIMIT).is_none());
|
||||
|
||||
let _ = v.pop();
|
||||
assert!(compress_weakly(&v, BOMB_LIMIT).is_some());
|
||||
assert!(compress_strongly(&v, BOMB_LIMIT).is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compress_and_decompress() {
|
||||
let v = vec![0; BOMB_LIMIT];
|
||||
|
||||
let compressed_weakly = compress_weakly(&v, BOMB_LIMIT).unwrap();
|
||||
let compressed_strongly = compress_strongly(&v, BOMB_LIMIT).unwrap();
|
||||
|
||||
assert!(compressed_weakly.starts_with(&ZSTD_PREFIX));
|
||||
assert!(compressed_strongly.starts_with(&ZSTD_PREFIX));
|
||||
|
||||
assert_eq!(&decompress(&compressed_weakly, BOMB_LIMIT).unwrap()[..], &v[..]);
|
||||
assert_eq!(&decompress(&compressed_strongly, BOMB_LIMIT).unwrap()[..], &v[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decompresses_only_when_magic() {
|
||||
let v = vec![0; BOMB_LIMIT + 1];
|
||||
|
||||
assert_eq!(&decompress(&v, BOMB_LIMIT).unwrap()[..], &v[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn possible_bomb_fails() {
|
||||
let encoded_bigger_than_bomb = vec![0; BOMB_LIMIT + 1];
|
||||
let mut buf = ZSTD_PREFIX.to_vec();
|
||||
|
||||
{
|
||||
let mut v = zstd::Encoder::new(&mut buf, 3).unwrap().auto_finish();
|
||||
v.write_all(&encoded_bigger_than_bomb[..]).unwrap();
|
||||
}
|
||||
|
||||
assert_eq!(decompress(&buf[..], BOMB_LIMIT).err(), Some(Error::PossibleBomb));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user