Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/sbor encoder decoder traits #597

Merged
merged 21 commits into from
Nov 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
4381102
refactor: Decode takes a generic Decoder
dhedey Nov 19, 2022
ba7cc38
feat: Decoder has a const max stack depth
dhedey Nov 19, 2022
7e29c18
refactor: Removed encode_any / decode_any
dhedey Nov 19, 2022
a43ae7f
refactor: Remove encode and decode methods
dhedey Nov 19, 2022
c38d43a
fix: Fix non fungible data derive and tests
dhedey Nov 19, 2022
749931b
feat: Encoder is now a trait
dhedey Nov 20, 2022
31e64c0
fix: Fix tests
dhedey Nov 20, 2022
6edd47c
fix: Fix some formatting
dhedey Nov 20, 2022
b12cca2
fix: Increase WASM stack size to 1024 to permit encoding deep object
dhedey Nov 20, 2022
7d6771e
fix: Fix a few test blueprints
dhedey Nov 20, 2022
6e1d210
fix: Formatting fix
dhedey Nov 20, 2022
c654fc7
refactor: Add more #[inline] attributes which somehow decreases WASM …
dhedey Nov 20, 2022
907b144
fix: Fix recursion test for doubling stack limit
dhedey Nov 20, 2022
c6b1c8c
fix: If size is too large, now returns EncodeError instead of panicking
dhedey Nov 20, 2022
1a5ce3c
refactor: Move track stack depth out of the traits for better hiding
dhedey Nov 20, 2022
1132184
docs: Improve docs on Encode/Decode/Encoder/Decoder
dhedey Nov 20, 2022
585cc2e
fix: Various SBOR implementation fixes
dhedey Nov 24, 2022
69ca560
tests: Add many SBOR depth tests; other markups
dhedey Nov 24, 2022
706e26d
fix: Fix compilation to not choke on 64 vecs
dhedey Nov 24, 2022
7f407d4
refactor: Renamed encoder/decoder body methods
dhedey Nov 24, 2022
dccfc1d
Merge branch 'develop' into feature/sbor-encoder-decoder-traits
dhedey Nov 24, 2022
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
5 changes: 2 additions & 3 deletions radix-engine-interface/src/api/api.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
use crate::api::types::ScryptoActor;
use crate::api::wasm_input::NativeFnInvocation;
use crate::crypto::Hash;
use crate::data::ScryptoCustomTypeId;
use crate::data::ScryptoDecode;
use crate::model::*;
use sbor::rust::fmt::Debug;
use sbor::rust::string::String;
use sbor::rust::vec::Vec;
use sbor::Decode;

use super::types::*;

pub trait ScryptoNativeInvocation: Into<NativeFnInvocation> + SysInvocation {}

pub trait SysInvocation {
type Output: Debug + Decode<ScryptoCustomTypeId>;
type Output: Debug + ScryptoDecode;
}

pub trait SysNativeInvokable<I: SysInvocation, E> {
Expand Down
21 changes: 13 additions & 8 deletions radix-engine-interface/src/data/custom_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ pub enum ScryptoCustomValue {
NonFungibleId(NonFungibleId),
}

impl CustomValue<ScryptoCustomTypeId> for ScryptoCustomValue {
fn encode_type_id(&self, encoder: &mut ScryptoEncoder) {
impl<E: Encoder<ScryptoCustomTypeId>> Encode<ScryptoCustomTypeId, E> for ScryptoCustomValue {
fn encode_type_id(&self, encoder: &mut E) -> Result<(), EncodeError> {
match self {
ScryptoCustomValue::PackageAddress(_) => {
encoder.write_type_id(SborTypeId::Custom(ScryptoCustomTypeId::PackageAddress))
Expand Down Expand Up @@ -105,7 +105,7 @@ impl CustomValue<ScryptoCustomTypeId> for ScryptoCustomValue {
}
}

fn encode_body(&self, encoder: &mut ScryptoEncoder) {
fn encode_body(&self, encoder: &mut E) -> Result<(), EncodeError> {
match self {
// TODO: vector free
ScryptoCustomValue::PackageAddress(v) => encoder.write_slice(&v.to_vec()),
Expand All @@ -119,13 +119,13 @@ impl CustomValue<ScryptoCustomTypeId> for ScryptoCustomValue {
ScryptoCustomValue::Vault(v) => encoder.write_slice(v.as_slice()),
ScryptoCustomValue::Expression(v) => {
let buf = v.to_vec();
encoder.write_size(buf.len());
encoder.write_size(buf.len())?;
encoder.write_slice(&buf)
}
ScryptoCustomValue::Blob(v) => encoder.write_slice(&v.to_vec()),
ScryptoCustomValue::NonFungibleAddress(v) => {
let buf = v.to_vec();
encoder.write_size(buf.len());
encoder.write_size(buf.len())?;
encoder.write_slice(&buf)
}
ScryptoCustomValue::Hash(v) => encoder.write_slice(&v.to_vec()),
Expand All @@ -137,16 +137,21 @@ impl CustomValue<ScryptoCustomTypeId> for ScryptoCustomValue {
ScryptoCustomValue::PreciseDecimal(v) => encoder.write_slice(&v.to_vec()),
ScryptoCustomValue::NonFungibleId(v) => {
let buf = v.to_vec();
encoder.write_size(buf.len());
encoder.write_size(buf.len())?;
encoder.write_slice(&buf)
}
}
}
}

impl<D: Decoder<ScryptoCustomTypeId>> Decode<ScryptoCustomTypeId, D> for ScryptoCustomValue {
fn decode_body_with_type_id(
decoder: &mut ScryptoDecoder,
type_id: ScryptoCustomTypeId,
decoder: &mut D,
type_id: SborTypeId<ScryptoCustomTypeId>,
) -> Result<Self, DecodeError> {
let SborTypeId::Custom(type_id) = type_id else {
return Err(DecodeError::UnexpectedCustomTypeId { actual: type_id.as_u8() });
};
match type_id {
ScryptoCustomTypeId::PackageAddress => {
let n = 27;
Expand Down
19 changes: 12 additions & 7 deletions radix-engine-interface/src/data/indexed_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ use utils::ContextualDisplay;

#[derive(Debug, Clone, PartialEq, Eq, TypeId, Encode, Decode)]
pub enum ScryptoValueDecodeError {
RawValueEncodeError(EncodeError),
TypedValueEncodeError(EncodeError),
DecodeError(DecodeError),
ValueIndexingError(ValueIndexingError),
}
Expand Down Expand Up @@ -51,13 +53,14 @@ impl IndexedScryptoValue {
Self::from_typed(&())
}

pub fn from_typed<T: Encode<ScryptoCustomTypeId>>(value: &T) -> Self {
let bytes = encode(value);
pub fn from_typed<T: ScryptoEncode + ?Sized>(value: &T) -> Self {
let bytes =
scrypto_encode(value).expect("Failed to encode trusted value for IndexedScryptoValue");
Self::from_slice(&bytes).expect("Failed to convert trusted value into IndexedScryptoValue")
}

pub fn from_slice(slice: &[u8]) -> Result<Self, ScryptoValueDecodeError> {
let value = decode_any(slice).map_err(ScryptoValueDecodeError::DecodeError)?;
let value = scrypto_decode(slice).map_err(ScryptoValueDecodeError::DecodeError)?;
Self::from_value(value)
}

Expand All @@ -69,7 +72,8 @@ impl IndexedScryptoValue {
}

Ok(Self {
raw: encode_any(&value),
raw: scrypto_encode(&value)
.map_err(|err| ScryptoValueDecodeError::RawValueEncodeError(err))?,
dom: value,
component_addresses: visitor.component_addresses,
resource_addresses: visitor.resource_addresses,
Expand Down Expand Up @@ -165,7 +169,8 @@ impl IndexedScryptoValue {
}
self.bucket_ids = new_bucket_ids;

self.raw = encode_any(&self.dom);
self.raw = scrypto_encode(&self.dom)
.expect("Previously encodable raw value is no longer encodable after replacement");

Ok(())
}
Expand Down Expand Up @@ -240,7 +245,7 @@ impl ScryptoCustomValueVisitor {
}
}

impl CustomValueVisitor<ScryptoCustomTypeId, ScryptoCustomValue> for ScryptoCustomValueVisitor {
impl CustomValueVisitor<ScryptoCustomValue> for ScryptoCustomValueVisitor {
type Err = ValueIndexingError;

fn visit(
Expand Down Expand Up @@ -332,7 +337,7 @@ mod tests {

#[test]
fn should_reject_duplicate_ids() {
let buckets = scrypto_encode(&vec![Bucket(0), Bucket(0)]);
let buckets = scrypto_encode(&vec![Bucket(0), Bucket(0)]).unwrap();
assert_eq!(
IndexedScryptoValue::from_slice(&buckets),
Err(ScryptoValueDecodeError::ValueIndexingError(
Expand Down
Loading