Skip to content
Open
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
84 changes: 71 additions & 13 deletions types/src/byte_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const WASM_STRING_PREFIX: &str = "byte-code-";

const BYTE_CODE_PREFIX: &str = "byte-code-";
const V1_WASM_PREFIX: &str = "v1-wasm-";
const V2_WASM_PREFIX: &str = "v2-wasm-";
const EMPTY_PREFIX: &str = "empty-";

/// Associated error type of `TryFrom<&[u8]>` for `ByteCodeHash`.
Expand Down Expand Up @@ -89,6 +90,8 @@ impl Display for FromStrError {
pub enum ByteCodeAddr {
/// An address for byte code to be executed against the V1 Casper execution engine.
V1CasperWasm(HashAddr),
/// An address for byte code to be executed against the V2 Casper execution engine.
V2CasperWasm(HashAddr),
/// An empty byte code record
Empty,
}
Expand All @@ -104,6 +107,7 @@ impl ByteCodeAddr {
match self {
Self::Empty => ByteCodeKind::Empty,
Self::V1CasperWasm(_) => ByteCodeKind::V1CasperWasm,
Self::V2CasperWasm(_) => ByteCodeKind::V2CasperWasm,
}
}

Expand All @@ -120,13 +124,16 @@ impl ByteCodeAddr {
(str, ByteCodeKind::Empty)
} else if let Some(str) = byte_code.strip_prefix(V1_WASM_PREFIX) {
(str, ByteCodeKind::V1CasperWasm)
} else if let Some(str) = byte_code.strip_prefix(V2_WASM_PREFIX) {
(str, ByteCodeKind::V2CasperWasm)
} else {
return Err(FromStrError::InvalidPrefix);
};
let addr = checksummed_hex::decode(addr_str).map_err(FromStrError::Hex)?;
let byte_code_addr = HashAddr::try_from(addr.as_ref()).map_err(FromStrError::Hash)?;
return match tag {
ByteCodeKind::V1CasperWasm => Ok(ByteCodeAddr::V1CasperWasm(byte_code_addr)),
ByteCodeKind::V2CasperWasm => Ok(ByteCodeAddr::V2CasperWasm(byte_code_addr)),
ByteCodeKind::Empty => Ok(ByteCodeAddr::Empty),
};
}
Expand All @@ -147,6 +154,7 @@ impl ToBytes for ByteCodeAddr {
+ match self {
Self::Empty => 0,
Self::V1CasperWasm(_) => KEY_HASH_LENGTH,
Self::V2CasperWasm(_) => KEY_HASH_LENGTH,
}
}

Expand All @@ -157,6 +165,10 @@ impl ToBytes for ByteCodeAddr {
writer.push(self.tag() as u8);
writer.extend(addr.to_bytes()?);
}
Self::V2CasperWasm(addr) => {
writer.push(self.tag() as u8);
writer.extend(addr.to_bytes()?);
}
}
Ok(())
}
Expand All @@ -171,6 +183,10 @@ impl FromBytes for ByteCodeAddr {
let (addr, remainder) = HashAddr::from_bytes(remainder)?;
Ok((ByteCodeAddr::new_wasm_addr(addr), remainder))
}
ByteCodeKind::V2CasperWasm => {
let (addr, remainder) = HashAddr::from_bytes(remainder)?;
Ok((ByteCodeAddr::V2CasperWasm(addr), remainder))
}
}
}
}
Expand All @@ -187,6 +203,15 @@ impl Display for ByteCodeAddr {
base16::encode_lower(&addr)
)
}
ByteCodeAddr::V2CasperWasm(addr) => {
write!(
f,
"{}{}{}",
BYTE_CODE_PREFIX,
V2_WASM_PREFIX,
base16::encode_lower(&addr)
)
}
ByteCodeAddr::Empty => {
write!(
f,
Expand All @@ -206,6 +231,9 @@ impl Debug for ByteCodeAddr {
ByteCodeAddr::V1CasperWasm(addr) => {
write!(f, "ByteCodeAddr::V1CasperWasm({:?})", addr)
}
ByteCodeAddr::V2CasperWasm(addr) => {
write!(f, "ByteCodeAddr::V2CasperWasm({:?})", addr)
}
ByteCodeAddr::Empty => {
write!(f, "ByteCodeAddr::Empty")
}
Expand All @@ -216,8 +244,9 @@ impl Debug for ByteCodeAddr {
#[cfg(any(feature = "testing", test))]
impl Distribution<ByteCodeAddr> for Standard {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> ByteCodeAddr {
match rng.gen_range(0..=1) {
match rng.gen_range(0..=2) {
1 => ByteCodeAddr::V1CasperWasm(rng.gen()),
2 => ByteCodeAddr::V2CasperWasm(rng.gen()),
0 => ByteCodeAddr::Empty,
_ => unreachable!(),
}
Expand Down Expand Up @@ -389,6 +418,8 @@ pub enum ByteCodeKind {
Empty = 0,
/// Byte code to be executed with the version 1 Casper execution engine.
V1CasperWasm = 1,
/// Byte code to be executed with the version 2 Casper execution engine.
V2CasperWasm = 2,
}

impl ToBytes for ByteCodeKind {
Expand All @@ -415,6 +446,9 @@ impl FromBytes for ByteCodeKind {
byte_code_kind if byte_code_kind == ByteCodeKind::V1CasperWasm as u8 => {
Ok((ByteCodeKind::V1CasperWasm, remainder))
}
byte_code_kind if byte_code_kind == ByteCodeKind::V2CasperWasm as u8 => {
Ok((ByteCodeKind::V2CasperWasm, remainder))
}
_ => Err(Error::Formatting),
}
}
Expand All @@ -429,16 +463,20 @@ impl Display for ByteCodeKind {
ByteCodeKind::V1CasperWasm => {
write!(f, "v1-casper-wasm")
}
ByteCodeKind::V2CasperWasm => {
write!(f, "v2-casper-wasm")
}
}
}
}

#[cfg(any(feature = "testing", test))]
impl Distribution<ByteCodeKind> for Standard {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> ByteCodeKind {
match rng.gen_range(0..=1) {
match rng.gen_range(0..=2) {
0 => ByteCodeKind::Empty,
1 => ByteCodeKind::V1CasperWasm,
2 => ByteCodeKind::V2CasperWasm,
_ => unreachable!(),
}
}
Expand Down Expand Up @@ -520,21 +558,27 @@ impl FromBytes for ByteCode {

#[cfg(test)]
mod tests {
use rand::RngCore;

use super::*;
use crate::testing::TestRng;

#[test]
fn debug_repr_of_short_wasm() {
fn debug_repr_of_short_wasm_v1() {
const SIZE: usize = 8;
let wasm_bytes = vec![0; SIZE];
let byte_code = ByteCode::new(ByteCodeKind::V1CasperWasm, wasm_bytes);
assert_eq!(format!("{:?}", byte_code), "ByteCode(0x0000000000000000)");
}

#[test]
fn debug_repr_of_long_wasm() {
fn debug_repr_of_short_wasm_v2() {
const SIZE: usize = 8;
let wasm_bytes = vec![0; SIZE];
let byte_code = ByteCode::new(ByteCodeKind::V2CasperWasm, wasm_bytes);
assert_eq!(format!("{:?}", byte_code), "ByteCode(0x0000000000000000)");
}

#[test]
fn debug_repr_of_long_wasm_v1() {
const SIZE: usize = 65;
let wasm_bytes = vec![0; SIZE];
let byte_code = ByteCode::new(ByteCodeKind::V1CasperWasm, wasm_bytes);
Expand All @@ -545,16 +589,30 @@ mod tests {
);
}

#[test]
fn debug_repr_of_long_wasm_v2() {
const SIZE: usize = 65;
let wasm_bytes = vec![0; SIZE];
let byte_code = ByteCode::new(ByteCodeKind::V2CasperWasm, wasm_bytes);
// String output is less than the bytes itself
assert_eq!(
format!("{:?}", byte_code),
"ByteCode(0x00000000000000000000000000000000...)"
);
}

#[test]
fn byte_code_bytesrepr_roundtrip() {
let rng = &mut TestRng::new();
let byte_code = ByteCode::new(rng.gen(), vec![]);
bytesrepr::test_serialization_roundtrip(&byte_code);
let bytes = vec![0; 1024];

let bytecode_v1 = ByteCode::new(ByteCodeKind::V1CasperWasm, bytes.clone());
bytesrepr::test_serialization_roundtrip(&bytecode_v1);

let bytecode_v2 = ByteCode::new(ByteCodeKind::V2CasperWasm, bytes.clone());
bytesrepr::test_serialization_roundtrip(&bytecode_v2);

let mut buffer = vec![0u8; rng.gen_range(1..100)];
rng.fill_bytes(buffer.as_mut());
let byte_code = ByteCode::new(rng.gen(), buffer);
bytesrepr::test_serialization_roundtrip(&byte_code);
let bytecode_empty = ByteCode::new(ByteCodeKind::Empty, Default::default());
bytesrepr::test_serialization_roundtrip(&bytecode_empty);
}

#[test]
Expand Down
4 changes: 1 addition & 3 deletions types/src/transaction/pricing_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,7 @@ impl PricingMode {
1 => PricingMode::Fixed {
gas_price_tolerance: rng.gen(),
},
2 => PricingMode::Reserved {
receipt: rng.gen(),
},
2 => PricingMode::Reserved { receipt: rng.gen() },
3 => PricingMode::GasLimited {
gas_limit: rng.gen(),
gas_price_tolerance: rng.gen(),
Expand Down