Skip to content

Commit

Permalink
fix: yield too large supertype from checks
Browse files Browse the repository at this point in the history
  • Loading branch information
kantai authored and wileyj committed May 9, 2023
1 parent 0ce213b commit baad222
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 6 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to the versioning scheme outlined in the [README.md](README.md).

## [2.3.0.0.2]

This is a high-priority hotfix release to address a bug in the
stacks-node miner logic which could impact miner availability.

This release is compatible with chainstate directories from 2.3.0.0.x and 2.1.0.0.x

## [2.3.0.0.1]

This is a hotfix release to update:
Expand Down
2 changes: 2 additions & 0 deletions clarity/src/vm/analysis/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub enum CheckErrors {
ValueOutOfBounds,
TypeSignatureTooDeep,
ExpectedName,
SupertypeTooLarge,

// match errors
BadMatchOptionSyntax(Box<CheckErrors>),
Expand Down Expand Up @@ -320,6 +321,7 @@ impl DiagnosableError for CheckErrors {
fn message(&self) -> String {
match &self {
CheckErrors::ExpectedLiteral => "expected a literal argument".into(),
CheckErrors::SupertypeTooLarge => "supertype of two types is too large".into(),
CheckErrors::BadMatchOptionSyntax(source) =>
format!("match on a optional type uses the following syntax: (match input some-name if-some-expression if-none-expression). Caused by: {}",
source.message()),
Expand Down
14 changes: 8 additions & 6 deletions clarity/src/vm/types/signatures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1073,8 +1073,9 @@ impl TypeSignature {
let entry_out = Self::least_supertype_v2_0(entry_a, entry_b)?;
type_map_out.insert(name.clone(), entry_out);
}
Ok(TupleTypeSignature::try_from(type_map_out).map(|x| x.into())
.expect("ERR: least_supertype_v2_0 attempted to construct a too-large supertype of two types"))
Ok(TupleTypeSignature::try_from(type_map_out)
.map(|x| x.into())
.map_err(|_| CheckErrors::SupertypeTooLarge)?)
}
(
SequenceType(SequenceSubtype::ListType(ListTypeData {
Expand All @@ -1095,7 +1096,7 @@ impl TypeSignature {
};
let max_len = cmp::max(len_a, len_b);
Ok(Self::list_of(entry_type, *max_len)
.expect("ERR: least_supertype_v2_0 attempted to construct a too-large supertype of two types"))
.map_err(|_| CheckErrors::SupertypeTooLarge)?)
}
(ResponseType(resp_a), ResponseType(resp_b)) => {
let ok_type =
Expand Down Expand Up @@ -1174,8 +1175,9 @@ impl TypeSignature {
let entry_out = Self::least_supertype_v2_1(entry_a, entry_b)?;
type_map_out.insert(name.clone(), entry_out);
}
Ok(TupleTypeSignature::try_from(type_map_out).map(|x| x.into())
.expect("ERR: least_supertype_v2_1 attempted to construct a too-large supertype of two types"))
Ok(TupleTypeSignature::try_from(type_map_out)
.map(|x| x.into())
.map_err(|_| CheckErrors::SupertypeTooLarge)?)
}
(
SequenceType(SequenceSubtype::ListType(ListTypeData {
Expand All @@ -1196,7 +1198,7 @@ impl TypeSignature {
};
let max_len = cmp::max(len_a, len_b);
Ok(Self::list_of(entry_type, *max_len)
.expect("ERR: least_supertype_v2_1 attempted to construct a too-large supertype of two types"))
.map_err(|_| CheckErrors::SupertypeTooLarge)?)
}
(ResponseType(resp_a), ResponseType(resp_b)) => {
let ok_type =
Expand Down
9 changes: 9 additions & 0 deletions src/chainstate/stacks/db/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,9 @@ pub fn handle_clarity_runtime_error(error: clarity_error) -> ClarityRuntimeTxErr
err_type: "short return/panic",
}
}
clarity_error::Interpreter(InterpreterError::Unchecked(CheckErrors::SupertypeTooLarge)) => {
ClarityRuntimeTxError::Rejectable(error)
}
clarity_error::Interpreter(InterpreterError::Unchecked(check_error)) => {
ClarityRuntimeTxError::AnalysisError(check_error)
}
Expand Down Expand Up @@ -1115,6 +1118,12 @@ impl StacksChainState {
}
}
}
if let clarity_error::Analysis(err) = &other_error {
if let CheckErrors::SupertypeTooLarge = err.err {
info!("Transaction {} is problematic and should have prevented this block from being relayed", tx.txid());
return Err(Error::ClarityError(other_error));
}
}
// this analysis isn't free -- convert to runtime error
let mut analysis_cost = clarity_tx.cost_so_far();
analysis_cost
Expand Down

0 comments on commit baad222

Please sign in to comment.