@@ -1420,6 +1420,9 @@ impl TransactionBuilder {
14201420 /// in the builder to be used when building the tx body.
14211421 /// In case there are no plutus input witnesses present - nothing will change
14221422 /// You can set specific hash value using `.set_script_data_hash`
1423+ /// NOTE: this function will check which language versions are used in the present scripts
1424+ /// and will assert and require for a corresponding cost-model to be present in the passed map.
1425+ /// Only the cost-models for the present language versions will be used in the hash calculation.
14231426 pub fn calc_script_data_hash ( & mut self , cost_models : & Costmdls ) -> Result < ( ) , JsError > {
14241427 let mut retained_cost_models = Costmdls :: new ( ) ;
14251428 if let Some ( pw) = self . inputs . get_plutus_input_scripts ( ) {
@@ -6010,5 +6013,77 @@ mod tests {
60106013 assert ! ( tx_builder. total_collateral. is_none( ) ) ;
60116014 assert ! ( tx_builder. collateral_return. is_none( ) ) ;
60126015 }
6016+
6017+ #[ test]
6018+ fn test_costmodel_retaining_for_v1 ( ) {
6019+ let mut tx_builder = create_reallistic_tx_builder ( ) ;
6020+ tx_builder. set_fee ( & to_bignum ( 42 ) ) ;
6021+ tx_builder. set_collateral ( & create_collateral ( ) ) ;
6022+
6023+ let ( script1, _) = plutus_script_and_hash ( 0 ) ;
6024+ let datum = PlutusData :: new_integer ( & BigInt :: from_str ( "42" ) . unwrap ( ) ) ;
6025+ let redeemer = Redeemer :: new (
6026+ & RedeemerTag :: new_spend ( ) ,
6027+ & to_bignum ( 0 ) ,
6028+ & datum,
6029+ & ExUnits :: new ( & to_bignum ( 1700 ) , & to_bignum ( 368100 ) ) ,
6030+ ) ;
6031+ tx_builder. add_plutus_script_input (
6032+ & PlutusWitness :: new ( & script1, & datum, & redeemer) ,
6033+ & TransactionInput :: new ( & genesis_id ( ) , 0 ) ,
6034+ & Value :: new ( & to_bignum ( 1_000_000 ) ) ,
6035+ ) ;
6036+
6037+ // Setting script data hash removes the error
6038+ tx_builder. calc_script_data_hash (
6039+ & TxBuilderConstants :: plutus_vasil_cost_models ( ) ,
6040+ ) . unwrap ( ) ;
6041+
6042+ // Using SAFE `.build_tx`
6043+ let res2 = tx_builder. build_tx ( ) ;
6044+ assert ! ( res2. is_ok( ) ) ;
6045+
6046+ let v1 = Language :: new_plutus_v1 ( ) ;
6047+ let v1_costmodel = TxBuilderConstants :: plutus_vasil_cost_models ( ) . get ( & v1) . unwrap ( ) ;
6048+ let mut retained_cost_models = Costmdls :: new ( ) ;
6049+ retained_cost_models. insert ( & v1, & v1_costmodel) ;
6050+
6051+ let data_hash = hash_script_data (
6052+ & Redeemers :: from ( vec ! [ redeemer. clone( ) ] ) ,
6053+ & retained_cost_models,
6054+ Some ( PlutusList :: from ( vec ! [ datum] ) ) ,
6055+ ) ;
6056+ assert_eq ! ( tx_builder. script_data_hash. unwrap( ) , data_hash) ;
6057+ }
6058+
6059+ #[ test]
6060+ fn test_costmodel_retaining_fails_on_missing_costmodel ( ) {
6061+ let mut tx_builder = create_reallistic_tx_builder ( ) ;
6062+ tx_builder. set_fee ( & to_bignum ( 42 ) ) ;
6063+ tx_builder. set_collateral ( & create_collateral ( ) ) ;
6064+
6065+ let ( script1, _) = plutus_script_and_hash ( 0 ) ;
6066+ let datum = PlutusData :: new_integer ( & BigInt :: from_str ( "42" ) . unwrap ( ) ) ;
6067+ let redeemer = Redeemer :: new (
6068+ & RedeemerTag :: new_spend ( ) ,
6069+ & to_bignum ( 0 ) ,
6070+ & datum,
6071+ & ExUnits :: new ( & to_bignum ( 1700 ) , & to_bignum ( 368100 ) ) ,
6072+ ) ;
6073+ tx_builder. add_plutus_script_input (
6074+ & PlutusWitness :: new ( & script1, & datum, & redeemer) ,
6075+ & TransactionInput :: new ( & genesis_id ( ) , 0 ) ,
6076+ & Value :: new ( & to_bignum ( 1_000_000 ) ) ,
6077+ ) ;
6078+
6079+ let v2 = Language :: new_plutus_v2 ( ) ;
6080+ let v2_costmodel = TxBuilderConstants :: plutus_vasil_cost_models ( ) . get ( & v2) . unwrap ( ) ;
6081+ let mut retained_cost_models = Costmdls :: new ( ) ;
6082+ retained_cost_models. insert ( & v2, & v2_costmodel) ;
6083+
6084+ // Setting script data hash removes the error
6085+ let calc_result = tx_builder. calc_script_data_hash ( & retained_cost_models) ;
6086+ assert ! ( calc_result. is_err( ) ) ;
6087+ }
60136088}
60146089
0 commit comments