@@ -1420,12 +1420,27 @@ 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- pub fn calc_script_data_hash ( & mut self , cost_models : & Costmdls ) {
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.
1426+ pub fn calc_script_data_hash ( & mut self , cost_models : & Costmdls ) -> Result < ( ) , JsError > {
1427+ let mut retained_cost_models = Costmdls :: new ( ) ;
14241428 if let Some ( pw) = self . inputs . get_plutus_input_scripts ( ) {
1425- let ( _, datums, redeemers) = pw. collect ( ) ;
1429+ let ( scripts, datums, redeemers) = pw. collect ( ) ;
1430+ for lang in Languages :: list ( ) . 0 {
1431+ if scripts. has_version ( & lang) {
1432+ match cost_models. get ( & lang) {
1433+ Some ( cost) => { retained_cost_models. insert ( & lang, & cost) ; } ,
1434+ _ => return Err ( JsError :: from_str (
1435+ & format ! ( "Missing cost model for language version: {:?}" , lang)
1436+ ) ) ,
1437+ }
1438+ }
1439+ }
14261440 self . script_data_hash =
1427- Some ( hash_script_data ( & redeemers, cost_models , Some ( datums) ) ) ;
1441+ Some ( hash_script_data ( & redeemers, & retained_cost_models , Some ( datums) ) ) ;
14281442 }
1443+ Ok ( ( ) )
14291444 }
14301445
14311446 /// Sets the specified hash value.
@@ -5033,7 +5048,7 @@ mod tests {
50335048 // Setting script data hash removes the error
50345049 tx_builder. calc_script_data_hash (
50355050 & TxBuilderConstants :: plutus_default_cost_models ( ) ,
5036- ) ;
5051+ ) . unwrap ( ) ;
50375052
50385053 // Using SAFE `.build_tx`
50395054 let res2 = tx_builder. build_tx ( ) ;
@@ -5094,7 +5109,7 @@ mod tests {
50945109 // Calc the script data hash
50955110 tx_builder. calc_script_data_hash (
50965111 & TxBuilderConstants :: plutus_default_cost_models ( ) ,
5097- ) ;
5112+ ) . unwrap ( ) ;
50985113
50995114 let tx: Transaction = tx_builder. build_tx ( ) . unwrap ( ) ;
51005115 assert ! ( tx. witness_set. redeemers. is_some( ) ) ;
@@ -5190,7 +5205,7 @@ mod tests {
51905205
51915206 tx_builder. calc_script_data_hash (
51925207 & TxBuilderConstants :: plutus_default_cost_models ( ) ,
5193- ) ;
5208+ ) . unwrap ( ) ;
51945209
51955210 let tx: Transaction = tx_builder. build_tx ( ) . unwrap ( ) ;
51965211
@@ -5335,7 +5350,7 @@ mod tests {
53355350
53365351 tx_builder. calc_script_data_hash (
53375352 & TxBuilderConstants :: plutus_default_cost_models ( ) ,
5338- ) ;
5353+ ) . unwrap ( ) ;
53395354
53405355 let w: & TransactionWitnessSet = & tx_builder. build_tx ( ) . unwrap ( ) . witness_set ;
53415356
@@ -5998,5 +6013,77 @@ mod tests {
59986013 assert ! ( tx_builder. total_collateral. is_none( ) ) ;
59996014 assert ! ( tx_builder. collateral_return. is_none( ) ) ;
60006015 }
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+ }
60016088}
60026089
0 commit comments