Skip to content

Commit 8fce86d

Browse files
committed
Address review feedback
1 parent b6abab2 commit 8fce86d

File tree

3 files changed

+56
-37
lines changed

3 files changed

+56
-37
lines changed

src/descriptor/segwitv0.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,9 @@ impl<Pk: MiniscriptKey> Wpkh<Pk> {
293293
pub fn new(pk: Pk) -> Result<Self, Error> {
294294
// do the top-level checks
295295
if pk.is_uncompressed() {
296-
Err(Error::ContextError(ScriptContextError::CompressedOnly))
296+
Err(Error::ContextError(ScriptContextError::CompressedOnly(
297+
pk.to_string(),
298+
)))
297299
} else {
298300
Ok(Self { pk: pk })
299301
}
@@ -376,7 +378,9 @@ where
376378
impl<Pk: MiniscriptKey> DescriptorTrait<Pk> for Wpkh<Pk> {
377379
fn sanity_check(&self) -> Result<(), Error> {
378380
if self.pk.is_uncompressed() {
379-
Err(Error::ContextError(ScriptContextError::CompressedOnly))
381+
Err(Error::ContextError(ScriptContextError::CompressedOnly(
382+
self.pk.to_string(),
383+
)))
380384
} else {
381385
Ok(())
382386
}

src/miniscript/context.rs

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use super::decode::ParseableKey;
2929
use {Miniscript, MiniscriptKey, Terminal};
3030

3131
/// Error for Script Context
32-
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
32+
#[derive(Clone, PartialEq, Eq, Debug)]
3333
pub enum ScriptContextError {
3434
/// Script Context does not permit PkH for non-malleability
3535
/// It is not possible to estimate the pubkey size at the creation
@@ -43,13 +43,13 @@ pub enum ScriptContextError {
4343
MalleableDupIf,
4444
/// Only Compressed keys allowed under current descriptor
4545
/// Segwitv0 fragments do not allow uncompressed pubkeys
46-
CompressedOnly,
46+
CompressedOnly(String),
4747
/// Tapscript descriptors cannot contain uncompressed keys
4848
/// Tap context can contain compressed or xonly
4949
UncompressedKeysNotAllowed,
5050
/// At least one satisfaction path in the Miniscript fragment has more than
5151
/// `MAX_STANDARD_P2WSH_STACK_ITEMS` (100) witness elements.
52-
MaxWitnessItemssExceeded,
52+
MaxWitnessItemssExceeded { actual: usize, limit: usize },
5353
/// At least one satisfaction path in the Miniscript fragment contains more
5454
/// than `MAX_OPS_PER_SCRIPT`(201) opcodes.
5555
MaxOpCountExceeded,
@@ -66,7 +66,7 @@ pub enum ScriptContextError {
6666
/// No Multi Node in Taproot context
6767
TaprootMultiDisabled,
6868
/// Stack size exceeded in script execution
69-
StackSizeLimitExceeded,
69+
StackSizeLimitExceeded { actual: usize, limit: usize },
7070
}
7171

7272
impl fmt::Display for ScriptContextError {
@@ -77,23 +77,24 @@ impl fmt::Display for ScriptContextError {
7777
ScriptContextError::MalleableDupIf => {
7878
write!(f, "DupIf is malleable under Legacy rules")
7979
}
80-
ScriptContextError::CompressedOnly => {
80+
ScriptContextError::CompressedOnly(ref pk) => {
8181
write!(
8282
f,
83-
"Only Compressed pubkeys are allowed in segwit context. X-only and uncompressed keys are forbidden"
83+
"Only Compressed pubkeys are allowed in segwit context. Found {}",
84+
pk
8485
)
8586
}
8687
ScriptContextError::UncompressedKeysNotAllowed => {
8788
write!(
8889
f,
89-
"Only x-only keys are allowed in tapscript checksig. \
90-
Compressed keys maybe specified in descriptor."
90+
"uncompressed keys cannot be used in Taproot descriptors."
9191
)
9292
}
93-
ScriptContextError::MaxWitnessItemssExceeded => write!(
93+
ScriptContextError::MaxWitnessItemssExceeded { actual, limit } => write!(
9494
f,
95-
"At least one spending path in the Miniscript fragment has more \
96-
witness items than MAX_STANDARD_P2WSH_STACK_ITEMS.",
95+
"At least one spending path in the Miniscript fragment has {} more \
96+
witness items than limit {}.",
97+
actual, limit
9798
),
9899
ScriptContextError::MaxOpCountExceeded => write!(
99100
f,
@@ -122,12 +123,13 @@ impl fmt::Display for ScriptContextError {
122123
)
123124
}
124125
ScriptContextError::TaprootMultiDisabled => {
125-
write!(f, "No Multi node in taproot context")
126+
write!(f, "Invalid use of Multi node in taproot context")
126127
}
127-
ScriptContextError::StackSizeLimitExceeded => {
128+
ScriptContextError::StackSizeLimitExceeded { actual, limit } => {
128129
write!(
129130
f,
130-
"Stack limit can exceed in atleast one script path during script execution"
131+
"Stack limit {} can exceed the allowed limit {} in at least one script path during script execution",
132+
actual, limit
131133
)
132134
}
133135
}
@@ -293,7 +295,7 @@ where
293295
fn pk_len<Pk: MiniscriptKey>(pk: &Pk) -> usize;
294296

295297
/// Local helper function to display error messages with context
296-
fn to_str() -> &'static str;
298+
fn name_str() -> &'static str;
297299
}
298300

299301
/// Legacy ScriptContext
@@ -378,7 +380,7 @@ impl ScriptContext for Legacy {
378380
}
379381
}
380382

381-
fn to_str() -> &'static str {
383+
fn name_str() -> &'static str {
382384
"Legacy/p2sh"
383385
}
384386
}
@@ -399,7 +401,10 @@ impl ScriptContext for Segwitv0 {
399401
witness: &[Vec<u8>],
400402
) -> Result<(), ScriptContextError> {
401403
if witness.len() > MAX_STANDARD_P2WSH_STACK_ITEMS {
402-
return Err(ScriptContextError::MaxWitnessItemssExceeded);
404+
return Err(ScriptContextError::MaxWitnessItemssExceeded {
405+
actual: witness.len(),
406+
limit: MAX_STANDARD_P2WSH_STACK_ITEMS,
407+
});
403408
}
404409
Ok(())
405410
}
@@ -414,13 +419,15 @@ impl ScriptContext for Segwitv0 {
414419
match ms.node {
415420
Terminal::PkK(ref pk) => {
416421
if pk.is_uncompressed() {
417-
return Err(ScriptContextError::CompressedOnly);
422+
return Err(ScriptContextError::CompressedOnly(pk.to_string()));
418423
}
419424
Ok(())
420425
}
421426
Terminal::Multi(_k, ref pks) => {
422-
if pks.iter().any(|pk| pk.is_uncompressed()) {
423-
return Err(ScriptContextError::CompressedOnly);
427+
for pk in pks.iter() {
428+
if pk.is_uncompressed() {
429+
return Err(ScriptContextError::CompressedOnly(pk.to_string()));
430+
}
424431
}
425432
Ok(())
426433
}
@@ -459,7 +466,10 @@ impl ScriptContext for Segwitv0 {
459466
// No possible satisfactions
460467
Err(_e) => Err(ScriptContextError::ImpossibleSatisfaction),
461468
Ok(max_witness_items) if max_witness_items > MAX_STANDARD_P2WSH_STACK_ITEMS => {
462-
Err(ScriptContextError::MaxWitnessItemssExceeded)
469+
Err(ScriptContextError::MaxWitnessItemssExceeded {
470+
actual: max_witness_items,
471+
limit: MAX_STANDARD_P2WSH_STACK_ITEMS,
472+
})
463473
}
464474
_ => Ok(()),
465475
}
@@ -476,7 +486,7 @@ impl ScriptContext for Segwitv0 {
476486
34
477487
}
478488

479-
fn to_str() -> &'static str {
489+
fn name_str() -> &'static str {
480490
"Segwitv0"
481491
}
482492
}
@@ -498,8 +508,12 @@ impl ScriptContext for Tap {
498508
fn check_witness<Pk: MiniscriptKey, Ctx: ScriptContext>(
499509
witness: &[Vec<u8>],
500510
) -> Result<(), ScriptContextError> {
511+
// Note that tapscript has a 1000 limit compared to 100 of segwitv0
501512
if witness.len() > MAX_STACK_SIZE {
502-
return Err(ScriptContextError::MaxWitnessItemssExceeded);
513+
return Err(ScriptContextError::MaxWitnessItemssExceeded {
514+
actual: witness.len(),
515+
limit: MAX_STACK_SIZE,
516+
});
503517
}
504518
Ok(())
505519
}
@@ -526,8 +540,6 @@ impl ScriptContext for Tap {
526540
Terminal::Multi(..) => {
527541
return Err(ScriptContextError::TaprootMultiDisabled);
528542
}
529-
// What happens to the Multi node in tapscript? Do we use it, create
530-
// a new fragment?
531543
_ => Ok(()),
532544
}
533545
}
@@ -549,7 +561,10 @@ impl ScriptContext for Tap {
549561
ms.ext.stack_elem_count_sat,
550562
) {
551563
if s + h > MAX_STACK_SIZE {
552-
return Err(ScriptContextError::StackSizeLimitExceeded);
564+
return Err(ScriptContextError::StackSizeLimitExceeded {
565+
actual: s + h,
566+
limit: MAX_STACK_SIZE,
567+
});
553568
}
554569
}
555570
Ok(())
@@ -583,7 +598,7 @@ impl ScriptContext for Tap {
583598
33
584599
}
585600

586-
fn to_str() -> &'static str {
601+
fn name_str() -> &'static str {
587602
"TapscriptCtx"
588603
}
589604
}
@@ -657,7 +672,7 @@ impl ScriptContext for BareCtx {
657672
}
658673
}
659674

660-
fn to_str() -> &'static str {
675+
fn name_str() -> &'static str {
661676
"BareCtx"
662677
}
663678
}
@@ -712,9 +727,9 @@ impl ScriptContext for NoChecks {
712727
panic!("Tried to compute a pk len bound on a no-checks miniscript")
713728
}
714729

715-
fn to_str() -> &'static str {
730+
fn name_str() -> &'static str {
716731
// Internally used code
717-
"NochecksCtx"
732+
"Nochecks"
718733
}
719734
}
720735

src/miniscript/decode.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -290,19 +290,19 @@ pub fn parse<Ctx: ScriptContext>(
290290
// pubkey
291291
Tk::Bytes33(pk) => {
292292
let ret = Ctx::Key::from_slice(pk)
293-
.map_err(|e| Error::PubKeyCtxError(e, Ctx::to_str()))?;
293+
.map_err(|e| Error::PubKeyCtxError(e, Ctx::name_str()))?;
294294
term.reduce0(Terminal::PkK(ret))?
295295
},
296296
Tk::Bytes65(pk) => {
297297
let ret = Ctx::Key::from_slice(pk)
298-
.map_err(|e| Error::PubKeyCtxError(e, Ctx::to_str()))?;
298+
.map_err(|e| Error::PubKeyCtxError(e, Ctx::name_str()))?;
299299
term.reduce0(Terminal::PkK(ret))?
300300
},
301301
// Note this does not collide with hash32 because they always followed by equal
302302
// and would be parsed in different branch. If we get a naked Bytes32, it must be
303303
// a x-only key
304304
Tk::Bytes32(pk) => {
305-
let ret = Ctx::Key::from_slice(pk).map_err(|e| Error::PubKeyCtxError(e, Ctx::to_str()))?;
305+
let ret = Ctx::Key::from_slice(pk).map_err(|e| Error::PubKeyCtxError(e, Ctx::name_str()))?;
306306
term.reduce0(Terminal::PkK(ret))?
307307
},
308308
// checksig
@@ -464,9 +464,9 @@ pub fn parse<Ctx: ScriptContext>(
464464
match_token!(
465465
tokens,
466466
Tk::Bytes33(pk) => keys.push(<Ctx::Key>::from_slice(pk)
467-
.map_err(|e| Error::PubKeyCtxError(e, Ctx::to_str()))?),
467+
.map_err(|e| Error::PubKeyCtxError(e, Ctx::name_str()))?),
468468
Tk::Bytes65(pk) => keys.push(<Ctx::Key>::from_slice(pk)
469-
.map_err(|e| Error::PubKeyCtxError(e, Ctx::to_str()))?),
469+
.map_err(|e| Error::PubKeyCtxError(e, Ctx::name_str()))?),
470470
);
471471
}
472472
let k = match_token!(

0 commit comments

Comments
 (0)