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

Value representation overhaul #234

Merged
merged 4 commits into from
Mar 8, 2023
Merged
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
2,769 changes: 1,466 additions & 1,303 deletions src/next/generated.rs

Large diffs are not rendered by default.

469 changes: 99 additions & 370 deletions src/next/scval_conversions.rs

Large diffs are not rendered by default.

131 changes: 47 additions & 84 deletions src/next/scval_validations.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![allow(clippy::missing_errors_doc)]

use super::{Error, ScMap, ScObject, ScVal};
use super::{Error, ScMap, ScVal};

pub trait Validate {
type Error;
@@ -12,14 +12,26 @@ impl Validate for ScVal {

fn validate(&self) -> Result<(), Self::Error> {
match self {
ScVal::U63(i) => {
// U63 is defined as valid per https://stellar.org/protocol/cap-46#comparison.
if *i >= 0 {
Ok(())
} else {
Err(Error::Invalid)
}
}
ScVal::U32(_)
| ScVal::I32(_)
| ScVal::Status(_)
| ScVal::Bool(_)
| ScVal::Void
| ScVal::U64(_)
| ScVal::I64(_)
| ScVal::Timepoint(_)
| ScVal::Duration(_)
| ScVal::U128(_)
| ScVal::I128(_)
| ScVal::U256(_)
| ScVal::I256(_)
| ScVal::Bytes(_)
| ScVal::String(_)
sisuresh marked this conversation as resolved.
Show resolved Hide resolved
| ScVal::Vec(Some(_))
| ScVal::ContractExecutable(_)
| ScVal::Address(_)
| ScVal::LedgerKeyContractExecutable
| ScVal::LedgerKeyNonce(_) => Ok(()),

ScVal::Symbol(s) => {
// Symbol is defined as valid per https://github.com/stellar/rs-stellar-contract-env/blob/94c1717516c8fad4ad65caa148183b9fcbc408db/stellar-contract-env-common/src/symbol.rs#L107-L111.
@@ -31,35 +43,8 @@ impl Validate for ScVal {
Err(Error::Invalid)
}
}

ScVal::Bitset(b) => {
// Bitset is defined as valid per https://github.com/stellar/rs-stellar-contract-env/blob/94c1717516c8fad4ad65caa148183b9fcbc408db/stellar-contract-env-common/src/bitset.rs#L53-L60.
if b & 0x0fff_ffff_ffff_ffff == *b {
Ok(())
} else {
Err(Error::Invalid)
}
}

ScVal::Object(None) => Err(Error::Invalid),

ScVal::Object(Some(o)) => match o {
ScObject::Map(m) => m.validate(),

// Other variants of ScObject are always valid.
ScObject::Vec(_)
| ScObject::U64(_)
| ScObject::I64(_)
| ScObject::U128(_)
| ScObject::I128(_)
| ScObject::Bytes(_)
| ScObject::ContractCode(_)
| ScObject::Address(_)
| ScObject::NonceKey(_) => Ok(()),
},

// Other variants of ScVal are always valid.
ScVal::U32(_) | ScVal::I32(_) | ScVal::Static(_) | ScVal::Status(_) => Ok(()),
ScVal::Vec(None) | ScVal::Map(None) => Err(Error::Invalid),
ScVal::Map(Some(m)) => m.validate(),
}
}
}
@@ -84,14 +69,6 @@ mod test {

use super::{Error, ScVal, Validate};

#[test]
fn u63() {
assert_eq!(ScVal::U63(0).validate(), Ok(()));
assert_eq!(ScVal::U63(1).validate(), Ok(()));
assert_eq!(ScVal::U63(i64::MAX).validate(), Ok(()));
assert_eq!(ScVal::U63(-1).validate(), Err(Error::Invalid));
}

#[test]
fn symbol() {
assert_eq!(
@@ -108,97 +85,83 @@ mod test {
);
}

#[test]
fn bitset() {
assert_eq!(ScVal::Bitset(0x0000_0000_0000_0000).validate(), Ok(()));
assert_eq!(ScVal::Bitset(0x0fff_ffff_ffff_ffff).validate(), Ok(()));
assert_eq!(
ScVal::Bitset(0x1000_0000_0000_0000).validate(),
Err(Error::Invalid)
);
assert_eq!(
ScVal::Bitset(0x1fff_ffff_ffff_ffff).validate(),
Err(Error::Invalid)
);
}

#[test]
#[cfg(feature = "alloc")]
fn map() {
use super::super::{ScMap, ScMapEntry, ScObject};
use super::super::{ScMap, ScMapEntry};
extern crate alloc;
use alloc::vec;
// Maps should be sorted by key and have no duplicates. The sort order
// is just the "normal" sort order on ScVal emitted by derive(PartialOrd).
assert_eq!(
ScVal::Object(Some(ScObject::Map(ScMap(
ScVal::Map(Some(ScMap(
vec![
ScMapEntry {
key: ScVal::U63(0),
key: ScVal::I64(0),
val: ScVal::U32(1),
},
ScMapEntry {
key: ScVal::U63(1),
val: ScVal::U63(1),
key: ScVal::I64(1),
val: ScVal::I64(1),
}
]
.try_into()
.unwrap()
))))
)))
.validate(),
Ok(())
);
assert_eq!(
ScVal::Object(Some(ScObject::Map(ScMap(
ScVal::Map(Some(ScMap(
vec![
ScMapEntry {
key: ScVal::U63(0),
val: ScVal::U63(1),
key: ScVal::I64(0),
val: ScVal::I64(1),
},
ScMapEntry {
key: ScVal::U63(1),
val: ScVal::U63(1),
key: ScVal::I64(1),
val: ScVal::I64(1),
}
]
.try_into()
.unwrap()
))))
)))
.validate(),
Ok(())
);
assert_eq!(
ScVal::Object(Some(ScObject::Map(ScMap(
ScVal::Map(Some(ScMap(
vec![
ScMapEntry {
key: ScVal::U63(2),
val: ScVal::U63(1),
key: ScVal::I64(2),
val: ScVal::I64(1),
},
ScMapEntry {
key: ScVal::U63(1),
val: ScVal::U63(1),
key: ScVal::I64(1),
val: ScVal::I64(1),
}
]
.try_into()
.unwrap()
))))
)))
.validate(),
Err(Error::Invalid)
);
assert_eq!(
ScVal::Object(Some(ScObject::Map(ScMap(
ScVal::Map(Some(ScMap(
vec![
ScMapEntry {
key: ScVal::U32(1),
val: ScVal::U63(1),
key: ScVal::I64(2),
val: ScVal::I64(1),
},
ScMapEntry {
key: ScVal::U63(2),
val: ScVal::U63(1),
key: ScVal::U32(1),
val: ScVal::I64(1),
},
]
.try_into()
.unwrap()
))))
)))
.validate(),
Err(Error::Invalid)
);
2 changes: 1 addition & 1 deletion xdr/next
2 changes: 1 addition & 1 deletion xdr/next-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
df18148747e807618acf4639db41c4fd6f0be9fc
32718f0a958d0ba3172af10fc8a55a5b551398b0