@@ -20,10 +20,13 @@ use super::{
2020 TypeChecker , TypingContext , check_argument_count, check_arguments_at_least,
2121 check_arguments_at_most, compute_typecheck_cost, no_type,
2222} ;
23- use crate :: vm:: analysis:: errors:: { StaticCheckError , StaticCheckErrorKind , SyntaxBindingErrorType } ;
23+ use crate :: vm:: analysis:: errors:: {
24+ StaticCheckError , StaticCheckErrorKind , SyntaxBindingErrorType , get_arguments_exact,
25+ } ;
2426use crate :: vm:: costs:: cost_functions:: ClarityCostFunction ;
2527use crate :: vm:: costs:: { CostErrors , CostTracker , analysis_typecheck_cost, runtime_cost} ;
2628use crate :: vm:: diagnostic:: DiagnosableError ;
29+ use crate :: vm:: functions:: bitcoin:: VERIFY_MERKLE_PROOF_MAX_DEPTH ;
2730use crate :: vm:: functions:: { NativeFunctions , handle_binding_list} ;
2831use crate :: vm:: types:: signatures:: {
2932 CallableSubtype , FunctionArgSignature , FunctionReturnsSignature , SequenceSubtype ,
@@ -868,6 +871,63 @@ fn check_get_tenure_info(
868871 Ok ( TypeSignature :: new_option ( block_info_prop. type_result ( ) ) ?)
869872}
870873
874+ fn check_verify_merkle_proof (
875+ checker : & mut TypeChecker ,
876+ args : & [ SymbolicExpression ] ,
877+ context : & TypingContext ,
878+ ) -> Result < TypeSignature , StaticCheckError > {
879+ let [ leaf_hash, root_hash, tx_index, tx_count, sibling_hashes] =
880+ get_arguments_exact :: < _ , 5 > ( args) ?;
881+
882+ check_argument_count ( 5 , args) ?;
883+ checker. type_check_expects ( leaf_hash, context, & TypeSignature :: BUFFER_32 ) ?;
884+ checker. type_check_expects ( root_hash, context, & TypeSignature :: BUFFER_32 ) ?;
885+ checker. type_check_expects ( tx_index, context, & TypeSignature :: UIntType ) ?;
886+ checker. type_check_expects ( tx_count, context, & TypeSignature :: UIntType ) ?;
887+ let siblings_type = TypeSignature :: list_of (
888+ TypeSignature :: BUFFER_32 ,
889+ VERIFY_MERKLE_PROOF_MAX_DEPTH ,
890+ )
891+ . map_err ( |_| {
892+ StaticCheckErrorKind :: Unreachable ( "FATAL: failed to build (list 24 (buff 32)) type" . into ( ) )
893+ } ) ?;
894+ checker. type_check_expects ( sibling_hashes, context, & siblings_type) ?;
895+ Ok ( TypeSignature :: BoolType )
896+ }
897+
898+ fn check_get_bitcoin_tx_output (
899+ checker : & mut TypeChecker ,
900+ args : & [ SymbolicExpression ] ,
901+ context : & TypingContext ,
902+ ) -> Result < TypeSignature , StaticCheckError > {
903+ let [ tx_bytes, vout_index] = get_arguments_exact :: < _ , 2 > ( args) ?;
904+
905+ checker. type_check_expects ( tx_bytes, context, & TypeSignature :: BUFFER_MAX ) ?;
906+ checker. type_check_expects ( vout_index, context, & TypeSignature :: UIntType ) ?;
907+
908+ let ok_type: TypeSignature = TupleTypeSignature :: try_from ( vec ! [
909+ (
910+ ClarityName :: from_literal( "script" ) ,
911+ TypeSignature :: BUFFER_1024 ,
912+ ) ,
913+ ( ClarityName :: from_literal( "amount" ) , TypeSignature :: UIntType ) ,
914+ ( ClarityName :: from_literal( "txid" ) , TypeSignature :: BUFFER_32 ) ,
915+ ] )
916+ . map_err ( |_| {
917+ StaticCheckErrorKind :: Unreachable (
918+ "FATAL: failed to build get-bitcoin-tx-output? ok-tuple type" . into ( ) ,
919+ )
920+ } ) ?
921+ . into ( ) ;
922+
923+ TypeSignature :: new_response ( ok_type, TypeSignature :: UIntType ) . map_err ( |_| {
924+ StaticCheckErrorKind :: Unreachable (
925+ "FATAL: failed to build get-bitcoin-tx-output? response type" . into ( ) ,
926+ )
927+ . into ( )
928+ } )
929+ }
930+
871931impl TypedNativeFunction {
872932 pub fn type_check_application (
873933 & self ,
@@ -1272,6 +1332,8 @@ impl TypedNativeFunction {
12721332 | AllowanceWithStacking
12731333 | AllowanceAll => Special ( SpecialNativeFunction ( & post_conditions:: check_allowance_err) ) ,
12741334 Secp256r1Verify => Special ( SpecialNativeFunction ( & check_secp256r1_verify) ) ,
1335+ VerifyMerkleProof => Special ( SpecialNativeFunction ( & check_verify_merkle_proof) ) ,
1336+ GetBitcoinTxOutput => Special ( SpecialNativeFunction ( & check_get_bitcoin_tx_output) ) ,
12751337 } ;
12761338
12771339 Ok ( out)
0 commit comments