Skip to content

Commit 13480cf

Browse files
Merge branch 'feat/aac-split-static-check-errors' of https://github.com/Jiloc/stacks-core into chore/add-custom-error-to-clarity-types
2 parents 542346f + be60d08 commit 13480cf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+4956
-2217
lines changed

clarity-types/src/errors/analysis.rs

Lines changed: 788 additions & 250 deletions
Large diffs are not rendered by default.

clarity-types/src/errors/mod.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub mod lexer;
2020

2121
use std::{error, fmt};
2222

23-
pub use analysis::{CheckErrorKind, StaticCheckError};
23+
pub use analysis::{CheckErrorKind, CommonCheckErrorKind, StaticCheckError, StaticCheckErrorKind};
2424
pub use ast::{ParseError, ParseErrorKind, ParseResult};
2525
pub use cost::CostErrors;
2626
pub use lexer::LexerError;
@@ -292,15 +292,21 @@ impl From<RuntimeError> for VmExecutionError {
292292
}
293293
}
294294

295+
impl From<CommonCheckErrorKind> for VmExecutionError {
296+
fn from(err: CommonCheckErrorKind) -> Self {
297+
VmExecutionError::Unchecked(err.into())
298+
}
299+
}
300+
295301
impl From<CheckErrorKind> for VmExecutionError {
296302
fn from(err: CheckErrorKind) -> Self {
297303
VmExecutionError::Unchecked(err)
298304
}
299305
}
300306

301-
impl From<(CheckErrorKind, &SymbolicExpression)> for VmExecutionError {
302-
fn from(err: (CheckErrorKind, &SymbolicExpression)) -> Self {
303-
VmExecutionError::Unchecked(err.0)
307+
impl From<(CommonCheckErrorKind, &SymbolicExpression)> for VmExecutionError {
308+
fn from(err: (CommonCheckErrorKind, &SymbolicExpression)) -> Self {
309+
VmExecutionError::Unchecked(err.0.into())
304310
}
305311
}
306312

clarity-types/src/tests/types/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use rstest::rstest;
1919
use stacks_common::types::StacksEpochId;
2020

2121
use crate::VmExecutionError;
22+
use crate::errors::analysis::CommonCheckErrorKind;
2223
use crate::errors::{CheckErrorKind, RuntimeError, VmInternalError};
2324
use crate::types::{
2425
ASCIIData, BuffData, CharType, ListTypeData, MAX_VALUE_SIZE, PrincipalData,
@@ -38,7 +39,7 @@ fn test_constructors() {
3839
);
3940
assert_eq!(
4041
ListTypeData::new_list(TypeSignature::IntType, MAX_VALUE_SIZE),
41-
Err(CheckErrorKind::ValueTooLarge)
42+
Err(CommonCheckErrorKind::ValueTooLarge)
4243
);
4344

4445
assert_eq!(

clarity-types/src/tests/types/signatures.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1515
use std::collections::HashSet;
1616

17-
use crate::errors::CheckErrorKind;
17+
use crate::errors::analysis::CommonCheckErrorKind;
1818
use crate::representations::CONTRACT_MAX_NAME_LENGTH;
1919
use crate::types::TypeSignature::{BoolType, IntType, ListUnionType, UIntType};
2020
use crate::types::signatures::{CallableSubtype, TypeSignature};
@@ -43,7 +43,7 @@ fn test_buffer_length_try_from_u32_trait() {
4343
assert_eq!(MAX_VALUE_SIZE, buffer.get_value());
4444

4545
let err = BufferLength::try_from(MAX_VALUE_SIZE + 1).unwrap_err();
46-
assert_eq!(CheckErrorKind::ValueTooLarge, err);
46+
assert_eq!(CommonCheckErrorKind::ValueTooLarge, err);
4747
}
4848

4949
#[test]
@@ -55,7 +55,7 @@ fn test_buffer_length_try_from_usize_trait() {
5555
assert_eq!(MAX_VALUE_SIZE, buffer.get_value());
5656

5757
let err = BufferLength::try_from(MAX_VALUE_SIZE as usize + 1).unwrap_err();
58-
assert_eq!(CheckErrorKind::ValueTooLarge, err);
58+
assert_eq!(CommonCheckErrorKind::ValueTooLarge, err);
5959
}
6060

6161
#[test]
@@ -67,10 +67,10 @@ fn test_buffer_length_try_from_i128_trait() {
6767
assert_eq!(MAX_VALUE_SIZE, buffer.get_value());
6868

6969
let err = BufferLength::try_from(MAX_VALUE_SIZE as i128 + 1).unwrap_err();
70-
assert_eq!(CheckErrorKind::ValueTooLarge, err);
70+
assert_eq!(CommonCheckErrorKind::ValueTooLarge, err);
7171

7272
let err = BufferLength::try_from(-1_i128).unwrap_err();
73-
assert_eq!(CheckErrorKind::ValueOutOfBounds, err);
73+
assert_eq!(CommonCheckErrorKind::ValueOutOfBounds, err);
7474
}
7575

7676
#[test]
@@ -229,7 +229,7 @@ fn test_string_utf8_length_try_from_u32_trait() {
229229
assert_eq!(MAX_UTF8_VALUE_SIZE, string.get_value());
230230

231231
let err = StringUTF8Length::try_from(MAX_UTF8_VALUE_SIZE + 1).unwrap_err();
232-
assert_eq!(CheckErrorKind::ValueTooLarge, err);
232+
assert_eq!(CommonCheckErrorKind::ValueTooLarge, err);
233233
}
234234

235235
#[test]
@@ -244,7 +244,7 @@ fn test_string_utf8_length_try_from_usize_trait() {
244244
assert_eq!(MAX_UTF8_VALUE_SIZE, string.get_value());
245245

246246
let err = StringUTF8Length::try_from(MAX_UTF8_VALUE_SIZE as usize + 1).unwrap_err();
247-
assert_eq!(CheckErrorKind::ValueTooLarge, err);
247+
assert_eq!(CommonCheckErrorKind::ValueTooLarge, err);
248248
}
249249

250250
#[test]
@@ -259,10 +259,10 @@ fn test_string_utf8_length_try_from_i128_trait() {
259259
assert_eq!(MAX_UTF8_VALUE_SIZE, string.get_value());
260260

261261
let err = StringUTF8Length::try_from(MAX_UTF8_VALUE_SIZE as i128 + 1).unwrap_err();
262-
assert_eq!(CheckErrorKind::ValueTooLarge, err);
262+
assert_eq!(CommonCheckErrorKind::ValueTooLarge, err);
263263

264264
let err = StringUTF8Length::try_from(-1_i128).unwrap_err();
265-
assert_eq!(CheckErrorKind::ValueOutOfBounds, err);
265+
assert_eq!(CommonCheckErrorKind::ValueOutOfBounds, err);
266266
}
267267

268268
#[test]
@@ -826,11 +826,11 @@ fn test_least_supertype() {
826826
for pair in bad_pairs {
827827
matches!(
828828
TypeSignature::least_supertype_v2_1(&pair.0, &pair.1).unwrap_err(),
829-
CheckErrorKind::TypeError(..)
829+
CommonCheckErrorKind::TypeError(..)
830830
);
831831
matches!(
832832
TypeSignature::least_supertype_v2_1(&pair.1, &pair.0).unwrap_err(),
833-
CheckErrorKind::TypeError(..)
833+
CommonCheckErrorKind::TypeError(..)
834834
);
835835
}
836836
}

clarity-types/src/types/mod.rs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pub use self::signatures::{
3636
AssetIdentifier, BufferLength, ListTypeData, SequenceSubtype, StringSubtype, StringUTF8Length,
3737
TupleTypeSignature, TypeSignature,
3838
};
39+
use crate::errors::analysis::CommonCheckErrorKind;
3940
use crate::errors::{CheckErrorKind, RuntimeError, VmExecutionError, VmInternalError};
4041
use crate::representations::{ClarityName, ContractName, SymbolicExpression};
4142

@@ -711,7 +712,7 @@ impl fmt::Display for UTF8Data {
711712
}
712713

713714
pub trait SequencedValue<T> {
714-
fn type_signature(&self) -> std::result::Result<TypeSignature, CheckErrorKind>;
715+
fn type_signature(&self) -> std::result::Result<TypeSignature, CommonCheckErrorKind>;
715716

716717
fn items(&self) -> &Vec<T>;
717718

@@ -736,7 +737,7 @@ impl SequencedValue<Value> for ListData {
736737
self.data.drain(..).collect()
737738
}
738739

739-
fn type_signature(&self) -> std::result::Result<TypeSignature, CheckErrorKind> {
740+
fn type_signature(&self) -> std::result::Result<TypeSignature, CommonCheckErrorKind> {
740741
Ok(TypeSignature::SequenceType(SequenceSubtype::ListType(
741742
self.type_signature.clone(),
742743
)))
@@ -756,9 +757,11 @@ impl SequencedValue<u8> for BuffData {
756757
self.data.drain(..).collect()
757758
}
758759

759-
fn type_signature(&self) -> std::result::Result<TypeSignature, CheckErrorKind> {
760+
fn type_signature(&self) -> std::result::Result<TypeSignature, CommonCheckErrorKind> {
760761
let buff_length = BufferLength::try_from(self.data.len()).map_err(|_| {
761-
CheckErrorKind::Expects("ERROR: Too large of a buffer successfully constructed.".into())
762+
CommonCheckErrorKind::Expects(
763+
"ERROR: Too large of a buffer successfully constructed.".into(),
764+
)
762765
})?;
763766
Ok(TypeSignature::SequenceType(SequenceSubtype::BufferType(
764767
buff_length,
@@ -779,9 +782,11 @@ impl SequencedValue<u8> for ASCIIData {
779782
self.data.drain(..).collect()
780783
}
781784

782-
fn type_signature(&self) -> std::result::Result<TypeSignature, CheckErrorKind> {
785+
fn type_signature(&self) -> std::result::Result<TypeSignature, CommonCheckErrorKind> {
783786
let buff_length = BufferLength::try_from(self.data.len()).map_err(|_| {
784-
CheckErrorKind::Expects("ERROR: Too large of a buffer successfully constructed.".into())
787+
CommonCheckErrorKind::Expects(
788+
"ERROR: Too large of a buffer successfully constructed.".into(),
789+
)
785790
})?;
786791
Ok(TypeSignature::SequenceType(SequenceSubtype::StringType(
787792
StringSubtype::ASCII(buff_length),
@@ -805,9 +810,11 @@ impl SequencedValue<Vec<u8>> for UTF8Data {
805810
self.data.drain(..).collect()
806811
}
807812

808-
fn type_signature(&self) -> std::result::Result<TypeSignature, CheckErrorKind> {
813+
fn type_signature(&self) -> std::result::Result<TypeSignature, CommonCheckErrorKind> {
809814
let str_len = StringUTF8Length::try_from(self.data.len()).map_err(|_| {
810-
CheckErrorKind::Expects("ERROR: Too large of a buffer successfully constructed.".into())
815+
CommonCheckErrorKind::Expects(
816+
"ERROR: Too large of a buffer successfully constructed.".into(),
817+
)
811818
})?;
812819
Ok(TypeSignature::SequenceType(SequenceSubtype::StringType(
813820
StringSubtype::UTF8(str_len),
@@ -823,19 +830,19 @@ impl SequencedValue<Vec<u8>> for UTF8Data {
823830
}
824831

825832
impl OptionalData {
826-
pub fn type_signature(&self) -> std::result::Result<TypeSignature, CheckErrorKind> {
833+
pub fn type_signature(&self) -> std::result::Result<TypeSignature, CommonCheckErrorKind> {
827834
let type_result = match self.data {
828835
Some(ref v) => TypeSignature::new_option(TypeSignature::type_of(v)?),
829836
None => TypeSignature::new_option(TypeSignature::NoType),
830837
};
831838
type_result.map_err(|_| {
832-
CheckErrorKind::Expects("Should not have constructed too large of a type.".into())
839+
CommonCheckErrorKind::Expects("Should not have constructed too large of a type.".into())
833840
})
834841
}
835842
}
836843

837844
impl ResponseData {
838-
pub fn type_signature(&self) -> std::result::Result<TypeSignature, CheckErrorKind> {
845+
pub fn type_signature(&self) -> std::result::Result<TypeSignature, CommonCheckErrorKind> {
839846
let type_result = match self.committed {
840847
true => TypeSignature::new_response(
841848
TypeSignature::type_of(&self.data)?,
@@ -847,7 +854,7 @@ impl ResponseData {
847854
),
848855
};
849856
type_result.map_err(|_| {
850-
CheckErrorKind::Expects("Should not have constructed too large of a type.".into())
857+
CommonCheckErrorKind::Expects("Should not have constructed too large of a type.".into())
851858
})
852859
}
853860
}

clarity-types/src/types/serialization.rs

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use stacks_common::util::hash::{hex_bytes, to_hex};
2323
use stacks_common::util::retry::BoundReader;
2424

2525
use super::{ListTypeData, TupleTypeSignature};
26+
use crate::errors::analysis::StaticCheckErrorKind;
2627
use crate::errors::{CheckErrorKind, IncomparableError, VmInternalError};
2728
use crate::representations::{ClarityName, ContractName, MAX_STRING_LEN};
2829
use crate::types::{
@@ -394,7 +395,7 @@ impl TypeSignature {
394395
/// size of a `(buff 1024*1024)` is `1+1024*1024` because of the
395396
/// type prefix byte. However, that is 1 byte larger than the maximum
396397
/// buffer size in Clarity.
397-
pub fn max_serialized_size(&self) -> Result<u32, CheckErrorKind> {
398+
pub fn max_serialized_size(&self) -> Result<u32, StaticCheckErrorKind> {
398399
let type_prefix_size = 1;
399400

400401
let max_output_size = match self {
@@ -405,7 +406,7 @@ impl TypeSignature {
405406
// `some` or similar with `result` types). So, when
406407
// serializing an object with a `NoType`, the other
407408
// branch should always be used.
408-
return Err(CheckErrorKind::CouldNotDetermineSerializationType);
409+
return Err(StaticCheckErrorKind::CouldNotDetermineSerializationType);
409410
}
410411
TypeSignature::IntType => 16,
411412
TypeSignature::UIntType => 16,
@@ -417,14 +418,14 @@ impl TypeSignature {
417418
.get_max_len()
418419
.checked_mul(list_type.get_list_item_type().max_serialized_size()?)
419420
.and_then(|x| x.checked_add(list_length_encode))
420-
.ok_or_else(|| CheckErrorKind::ValueTooLarge)?
421+
.ok_or_else(|| StaticCheckErrorKind::ValueTooLarge)?
421422
}
422423
TypeSignature::SequenceType(SequenceSubtype::BufferType(buff_length)) => {
423424
// u32 length as big-endian bytes
424425
let buff_length_encode = 4;
425426
u32::from(buff_length)
426427
.checked_add(buff_length_encode)
427-
.ok_or_else(|| CheckErrorKind::ValueTooLarge)?
428+
.ok_or_else(|| StaticCheckErrorKind::ValueTooLarge)?
428429
}
429430
TypeSignature::SequenceType(SequenceSubtype::StringType(StringSubtype::ASCII(
430431
length,
@@ -434,7 +435,7 @@ impl TypeSignature {
434435
// ascii is 1-byte per character
435436
u32::from(length)
436437
.checked_add(str_length_encode)
437-
.ok_or_else(|| CheckErrorKind::ValueTooLarge)?
438+
.ok_or_else(|| StaticCheckErrorKind::ValueTooLarge)?
438439
}
439440
TypeSignature::SequenceType(SequenceSubtype::StringType(StringSubtype::UTF8(
440441
length,
@@ -445,7 +446,7 @@ impl TypeSignature {
445446
u32::from(length)
446447
.checked_mul(4)
447448
.and_then(|x| x.checked_add(str_length_encode))
448-
.ok_or_else(|| CheckErrorKind::ValueTooLarge)?
449+
.ok_or_else(|| StaticCheckErrorKind::ValueTooLarge)?
449450
}
450451
TypeSignature::PrincipalType
451452
| TypeSignature::CallableType(_)
@@ -468,7 +469,7 @@ impl TypeSignature {
468469
.checked_add(1) // length of key-name
469470
.and_then(|x| x.checked_add(key.len() as u32)) // ClarityName is ascii-only, so 1 byte per length
470471
.and_then(|x| x.checked_add(value_size))
471-
.ok_or_else(|| CheckErrorKind::ValueTooLarge)?;
472+
.ok_or_else(|| StaticCheckErrorKind::ValueTooLarge)?;
472473
}
473474
total_size
474475
}
@@ -477,25 +478,25 @@ impl TypeSignature {
477478
Ok(size) => size,
478479
// if NoType, then this is just serializing a none
479480
// value, which is only the type prefix
480-
Err(CheckErrorKind::CouldNotDetermineSerializationType) => 0,
481+
Err(StaticCheckErrorKind::CouldNotDetermineSerializationType) => 0,
481482
Err(e) => return Err(e),
482483
}
483484
}
484485
TypeSignature::ResponseType(response_types) => {
485486
let (ok_type, err_type) = response_types.as_ref();
486487
let (ok_type_max_size, no_ok_type) = match ok_type.max_serialized_size() {
487488
Ok(size) => (size, false),
488-
Err(CheckErrorKind::CouldNotDetermineSerializationType) => (0, true),
489+
Err(StaticCheckErrorKind::CouldNotDetermineSerializationType) => (0, true),
489490
Err(e) => return Err(e),
490491
};
491492
let err_type_max_size = match err_type.max_serialized_size() {
492493
Ok(size) => size,
493-
Err(CheckErrorKind::CouldNotDetermineSerializationType) => {
494+
Err(StaticCheckErrorKind::CouldNotDetermineSerializationType) => {
494495
if no_ok_type {
495496
// if both the ok type and the error type are NoType,
496-
// throw a CheckErrorKind. This should not be possible, but the check
497+
// throw a StaticCheckErrorKind. This should not be possible, but the check
497498
// is done out of caution.
498-
return Err(CheckErrorKind::CouldNotDetermineSerializationType);
499+
return Err(StaticCheckErrorKind::CouldNotDetermineSerializationType);
499500
} else {
500501
0
501502
}
@@ -505,13 +506,13 @@ impl TypeSignature {
505506
cmp::max(ok_type_max_size, err_type_max_size)
506507
}
507508
TypeSignature::ListUnionType(_) => {
508-
return Err(CheckErrorKind::CouldNotDetermineSerializationType);
509+
return Err(StaticCheckErrorKind::CouldNotDetermineSerializationType);
509510
}
510511
};
511512

512513
max_output_size
513514
.checked_add(type_prefix_size)
514-
.ok_or_else(|| CheckErrorKind::ValueTooLarge)
515+
.ok_or_else(|| StaticCheckErrorKind::ValueTooLarge)
515516
}
516517
}
517518

@@ -612,8 +613,8 @@ impl Value {
612613
TypePrefix::Buffer => {
613614
let mut buffer_len = [0; 4];
614615
r.read_exact(&mut buffer_len)?;
615-
let buffer_len = BufferLength::try_from(u32::from_be_bytes(buffer_len))?;
616-
616+
let buffer_len = BufferLength::try_from(u32::from_be_bytes(buffer_len))
617+
.map_err(CheckErrorKind::from)?;
617618
if let Some(x) = &expected_type {
618619
let passed_test = match x {
619620
TypeSignature::SequenceType(SequenceSubtype::BufferType(
@@ -844,7 +845,8 @@ impl Value {
844845
TypePrefix::StringASCII => {
845846
let mut buffer_len = [0; 4];
846847
r.read_exact(&mut buffer_len)?;
847-
let buffer_len = BufferLength::try_from(u32::from_be_bytes(buffer_len))?;
848+
let buffer_len = BufferLength::try_from(u32::from_be_bytes(buffer_len))
849+
.map_err(CheckErrorKind::from)?;
848850

849851
if let Some(x) = &expected_type {
850852
let passed_test = match x {
@@ -869,7 +871,8 @@ impl Value {
869871
TypePrefix::StringUTF8 => {
870872
let mut total_len = [0; 4];
871873
r.read_exact(&mut total_len)?;
872-
let total_len = BufferLength::try_from(u32::from_be_bytes(total_len))?;
874+
let total_len = BufferLength::try_from(u32::from_be_bytes(total_len))
875+
.map_err(CheckErrorKind::from)?;
873876

874877
let mut data: Vec<u8> = vec![0; u32::from(total_len) as usize];
875878

0 commit comments

Comments
 (0)