Skip to content

Commit

Permalink
Merge branch 'main' into aw/cacher-hasher
Browse files Browse the repository at this point in the history
  • Loading branch information
aumetra committed Sep 27, 2024
2 parents bce8adf + cf413c5 commit dfa0c3a
Show file tree
Hide file tree
Showing 22 changed files with 343 additions and 45 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contracts/burner/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contracts/crypto-verify/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contracts/cyberpunk/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contracts/empty/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contracts/floaty/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contracts/hackatom/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contracts/ibc-callbacks/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contracts/ibc-reflect-send/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contracts/ibc-reflect/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contracts/queue/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contracts/reflect/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contracts/staking/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contracts/virus/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/vm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ wasmer = { version = "=4.3.7", default-features = false, features = [
"singlepass",
] }
wasmer-middlewares = "=4.3.7"
wasmer-types = "=4.3.7"
strum = { version = "0.26.2", default-features = false, features = ["derive"] }
# For heap profiling. Only used in the "heap_profiling" example. This has to be a non-dev dependency
# because cargo currently does not support optional dev-dependencies.
Expand Down
7 changes: 7 additions & 0 deletions packages/vm/src/errors/communication_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ pub enum CommunicationError {
#[from]
source: RegionValidationError,
},
/// When the contract supplies invalid section data to the host. See also `decode_sections` [crate::sections::decode_sections].
#[error("Got an invalid section: {}", msg)]
InvalidSection { msg: String },
/// Whenever UTF-8 bytes cannot be decoded into a unicode string, e.g. in String::from_utf8 or str::from_utf8.
#[error("Cannot decode UTF8 bytes into string: {}", msg)]
InvalidUtf8 { msg: String },
Expand Down Expand Up @@ -56,6 +59,10 @@ impl CommunicationError {
CommunicationError::InvalidOrder { value }
}

pub(crate) fn invalid_section(msg: impl Into<String>) -> Self {
CommunicationError::InvalidSection { msg: msg.into() }
}

#[allow(dead_code)]
pub(crate) fn invalid_utf8(msg: impl ToString) -> Self {
CommunicationError::InvalidUtf8 {
Expand Down
6 changes: 3 additions & 3 deletions packages/vm/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -730,9 +730,9 @@ pub fn do_ed25519_batch_verify<
(EDDSA_PUBKEY_LEN + 4) * MAX_COUNT_ED25519_BATCH,
)?;

let messages = decode_sections(&messages);
let signatures = decode_sections(&signatures);
let public_keys = decode_sections(&public_keys);
let messages = decode_sections(&messages)?;
let signatures = decode_sections(&signatures)?;
let public_keys = decode_sections(&public_keys)?;

let gas_cost = if public_keys.len() == 1 {
&data.gas_config.ed25519_batch_verify_one_pubkey_cost
Expand Down
8 changes: 4 additions & 4 deletions packages/vm/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -914,7 +914,7 @@ mod tests {

let report2 = instance.create_gas_report();
assert_eq!(report2.used_externally, 251);
assert_eq!(report2.used_internally, 17457465);
assert_eq!(report2.used_internally, 21589990);
assert_eq!(report2.limit, LIMIT);
assert_eq!(
report2.remaining,
Expand Down Expand Up @@ -1106,7 +1106,7 @@ mod tests {
.unwrap();

let init_used = orig_gas - instance.get_gas_left();
assert_eq!(init_used, 17457716);
assert_eq!(init_used, 21590241);
}

#[test]
Expand All @@ -1131,7 +1131,7 @@ mod tests {
.unwrap();

let execute_used = gas_before_execute - instance.get_gas_left();
assert_eq!(execute_used, 21041196);
assert_eq!(execute_used, 26961511);
}

#[test]
Expand Down Expand Up @@ -1174,6 +1174,6 @@ mod tests {
);

let query_used = gas_before_query - instance.get_gas_left();
assert_eq!(query_used, 12631261);
assert_eq!(query_used, 15938086);
}
}
69 changes: 43 additions & 26 deletions packages/vm/src/sections.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use crate::conversion::to_u32;
use crate::errors::VmResult;
use crate::{CommunicationError, VmResult};

/// Decodes sections of data into multiple slices.
///
/// Each encoded section is suffixed by a section length, encoded as big endian uint32.
///
/// See also: `encode_section`.
#[allow(dead_code)]
pub fn decode_sections(data: &[u8]) -> Vec<&[u8]> {
/// See also: [`encode_sections`].
pub fn decode_sections(data: &[u8]) -> Result<Vec<&[u8]>, CommunicationError> {
let mut result: Vec<&[u8]> = vec![];
let mut remaining_len = data.len();
while remaining_len >= 4 {
Expand All @@ -17,11 +16,20 @@ pub fn decode_sections(data: &[u8]) -> Vec<&[u8]> {
data[remaining_len - 2],
data[remaining_len - 1],
]) as usize;
result.push(&data[remaining_len - 4 - tail_len..remaining_len - 4]);
remaining_len -= 4 + tail_len;
let tail_len_idx = remaining_len - 4; // index of the first byte of the tail length
let section_start = tail_len_idx
.checked_sub(tail_len)
.ok_or_else(|| CommunicationError::invalid_section("section length overflow"))?;
result.push(&data[section_start..tail_len_idx]);
remaining_len = section_start;
}
if remaining_len > 0 {
return Err(CommunicationError::invalid_section(
"extra data outside of any section",
));
}
result.reverse();
result
Ok(result)
}

/// Encodes multiple sections of data into one vector.
Expand Down Expand Up @@ -57,52 +65,61 @@ mod tests {

#[test]
fn decode_sections_works_for_empty_sections() {
let dec = decode_sections(&[]);
let dec = decode_sections(&[]).unwrap();
assert_eq!(dec.len(), 0);
let dec = decode_sections(b"\0\0\0\0");
let dec = decode_sections(b"\0\0\0\0").unwrap();
assert_eq!(dec, &[&[0u8; 0]]);
let dec = decode_sections(b"\0\0\0\0\0\0\0\0");
let dec = decode_sections(b"\0\0\0\0\0\0\0\0").unwrap();
assert_eq!(dec, &[&[0u8; 0]; 2]);
let dec = decode_sections(b"\0\0\0\0\0\0\0\0\0\0\0\0");
let dec = decode_sections(b"\0\0\0\0\0\0\0\0\0\0\0\0").unwrap();
assert_eq!(dec, &[&[0u8; 0]; 3]);
// ignores "trailing" stuff
let dec = decode_sections(b"\0\0\0\0\0\0\0\0\0\0\0");
assert_eq!(dec, &[&[0u8; 0]; 2]);
}

#[test]
fn decode_sections_works_for_one_element() {
let dec = decode_sections(b"\xAA\0\0\0\x01");
let dec = decode_sections(b"\xAA\0\0\0\x01").unwrap();
assert_eq!(dec, &[vec![0xAA]]);
let dec = decode_sections(b"\xAA\xBB\0\0\0\x02");
let dec = decode_sections(b"\xAA\xBB\0\0\0\x02").unwrap();
assert_eq!(dec, &[vec![0xAA, 0xBB]]);
let dec = decode_sections(b"\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\0\0\x01\x15");
let dec = decode_sections(b"\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\0\0\x01\x15").unwrap();
assert_eq!(dec, &[vec![0x9D; 277]]);
}

#[test]
fn decode_sections_works_for_two_elements() {
let data = b"\xAA\0\0\0\x01\xBB\xCC\0\0\0\x02".to_vec();
assert_eq!(decode_sections(&data), &[vec![0xAA], vec![0xBB, 0xCC]]);
assert_eq!(
decode_sections(&data).unwrap(),
&[vec![0xAA], vec![0xBB, 0xCC]]
);
let data = b"\xDE\xEF\x62\0\0\0\x03\0\0\0\0".to_vec();
assert_eq!(decode_sections(&data), &[vec![0xDE, 0xEF, 0x62], vec![]]);
assert_eq!(
decode_sections(&data).unwrap(),
&[vec![0xDE, 0xEF, 0x62], vec![]]
);
let data = b"\0\0\0\0\xDE\xEF\x62\0\0\0\x03".to_vec();
assert_eq!(decode_sections(&data), &[vec![], vec![0xDE, 0xEF, 0x62]]);
assert_eq!(
decode_sections(&data).unwrap(),
&[vec![], vec![0xDE, 0xEF, 0x62]]
);
let data = b"\0\0\0\0\0\0\0\0".to_vec();
assert_eq!(decode_sections(&data), &[vec![0u8; 0], vec![]]);
assert_eq!(decode_sections(&data).unwrap(), &[vec![0u8; 0], vec![]]);
let data = b"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\x13\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\0\0\x01\x15".to_vec();
assert_eq!(decode_sections(&data), &[vec![0xFF; 19], vec![0x9D; 277]]);
assert_eq!(
decode_sections(&data).unwrap(),
&[vec![0xFF; 19], vec![0x9D; 277]]
);
}

#[test]
fn decode_sections_works_for_multiple_elements() {
let dec = decode_sections(b"\xAA\0\0\0\x01");
let dec = decode_sections(b"\xAA\0\0\0\x01").unwrap();
assert_eq!(dec, &[vec![0xAA]]);
let dec = decode_sections(b"\xAA\0\0\0\x01\xDE\xDE\0\0\0\x02");
let dec = decode_sections(b"\xAA\0\0\0\x01\xDE\xDE\0\0\0\x02").unwrap();
assert_eq!(dec, &[vec![0xAA], vec![0xDE, 0xDE]]);
let dec = decode_sections(b"\xAA\0\0\0\x01\xDE\xDE\0\0\0\x02\0\0\0\0");
let dec = decode_sections(b"\xAA\0\0\0\x01\xDE\xDE\0\0\0\x02\0\0\0\0").unwrap();
assert_eq!(dec, &[vec![0xAA], vec![0xDE, 0xDE], vec![]]);
let dec = decode_sections(b"\xAA\0\0\0\x01\xDE\xDE\0\0\0\x02\0\0\0\0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\x13");
let dec = decode_sections(b"\xAA\0\0\0\x01\xDE\xDE\0\0\0\x02\0\0\0\0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\x13").unwrap();
assert_eq!(dec, &[vec![0xAA], vec![0xDE, 0xDE], vec![], vec![0xFF; 19]]);
}

Expand Down
17 changes: 5 additions & 12 deletions packages/vm/src/wasm_backend/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ use wasmer::NativeEngineExt;
use wasmer::{
sys::BaseTunables, wasmparser::Operator, CompilerConfig, Engine, Pages, Target, WASM_PAGE_SIZE,
};
use wasmer_middlewares::Metering;

use crate::size::Size;

use super::gatekeeper::Gatekeeper;
use super::limiting_tunables::LimitingTunables;
use super::metering::{is_accounting, Metering};

/// WebAssembly linear memory objects have sizes measured in pages. Each page
/// is 65536 (2^16) bytes. In WebAssembly version 1, a linear memory can have at
Expand All @@ -31,17 +31,10 @@ fn cost(operator: &Operator) -> u64 {
// compared to newly compiled ones.
const GAS_PER_OPERATION: u64 = 115;

match operator {
Operator::Loop { .. }
| Operator::End
| Operator::Else
| Operator::Br { .. }
| Operator::BrTable { .. }
| Operator::BrIf { .. }
| Operator::Call { .. }
| Operator::CallIndirect { .. }
| Operator::Return => GAS_PER_OPERATION * 14,
_ => GAS_PER_OPERATION,
if is_accounting(operator) {
GAS_PER_OPERATION * 14
} else {
GAS_PER_OPERATION
}
}

Expand Down
Loading

0 comments on commit dfa0c3a

Please sign in to comment.