Skip to content

Commit

Permalink
Add CallData to testing env
Browse files Browse the repository at this point in the history
  • Loading branch information
cmichi committed Mar 1, 2022
1 parent 39f3935 commit e60baf2
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 0 deletions.
98 changes: 98 additions & 0 deletions crates/env/src/engine/experimental_off_chain/call_data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright 2018-2022 Parity Technologies (UK) Ltd.
//
// 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.

use crate::call::Selector;
use ink_prelude::{
vec,
vec::Vec,
};

/// The raw ABI respecting input data to a call.
///
/// # Note
///
/// The first four bytes are the function selector and the rest are SCALE encoded inputs.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CallData {
/// Already encoded function selector and inputs.
///
/// # Note
///
/// Has the invariant of always holding at least 4 bytes (the selector).
bytes: Vec<u8>,
}

impl CallData {
/// Creates new call ABI data for the given selector.
pub fn new(selector: Selector) -> Self {
let bytes = selector.to_bytes();
Self {
bytes: vec![bytes[0], bytes[1], bytes[2], bytes[3]],
}
}

/// Pushes the given argument onto the call ABI data in encoded form.
pub fn push_arg<A>(&mut self, arg: &A)
where
A: scale::Encode,
{
arg.encode_to(&mut self.bytes)
}

/// Returns the selector of `self`.
pub fn selector(&self) -> Selector {
debug_assert!(self.bytes.len() >= 4);
let bytes = [self.bytes[0], self.bytes[1], self.bytes[2], self.bytes[3]];
bytes.into()
}

/// Returns the underlying bytes of the encoded input parameters.
pub fn params(&self) -> &[u8] {
debug_assert!(self.bytes.len() >= 4);
&self.bytes[4..]
}

/// Returns the underlying byte representation.
pub fn to_bytes(&self) -> &[u8] {
&self.bytes
}
}

impl scale::Encode for CallData {
fn size_hint(&self) -> usize {
self.bytes.len()
}

fn encode_to<T: scale::Output + ?Sized>(&self, dest: &mut T) {
dest.write(self.bytes.as_slice());
}
}

impl scale::Decode for CallData {
fn decode<I: scale::Input>(
input: &mut I,
) -> core::result::Result<Self, scale::Error> {
let remaining_len = input.remaining_len().unwrap_or(None).unwrap_or(0);
let mut bytes = Vec::with_capacity(remaining_len);
while let Ok(byte) = input.read_byte() {
bytes.push(byte);
}
if bytes.len() < 4 {
return Err(scale::Error::from(
"require at least 4 bytes for input data",
))
}
Ok(Self { bytes })
}
}
3 changes: 3 additions & 0 deletions crates/env/src/engine/experimental_off_chain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.

mod call_data;
mod impls;
pub mod test_api;
mod types;

#[cfg(test)]
mod tests;

pub use call_data::CallData;

use super::OnInstance;
use crate::Error;

Expand Down
1 change: 1 addition & 0 deletions crates/env/src/engine/experimental_off_chain/test_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use core::fmt::Debug;
use ink_engine::test_api::RecordedDebugMessages;
use std::panic::UnwindSafe;

pub use super::call_data::CallData;
pub use ink_engine::ChainExtension;

/// Record for an emitted event.
Expand Down

0 comments on commit e60baf2

Please sign in to comment.