@@ -200,8 +200,6 @@ impl ConstrPlutusData {
200200 }
201201}
202202
203- const COST_MODEL_OP_COUNT : usize = 166 ;
204-
205203#[ wasm_bindgen]
206204#[ derive( Clone , Debug , Eq , Ord , PartialEq , PartialOrd ) ]
207205pub struct CostModel ( Vec < Int > ) ;
@@ -210,26 +208,32 @@ to_from_bytes!(CostModel);
210208
211209#[ wasm_bindgen]
212210impl CostModel {
211+
212+ /// Creates a new CostModels instance of an unrestricted length
213213 pub fn new ( ) -> Self {
214- let mut costs = Vec :: with_capacity ( COST_MODEL_OP_COUNT ) ;
215- for _ in 0 .. COST_MODEL_OP_COUNT {
216- costs. push ( Int :: new_i32 ( 0 ) ) ;
217- }
218- Self ( costs)
214+ Self ( Vec :: new ( ) )
219215 }
220216
217+ /// Sets the cost at the specified index to the specified value.
218+ /// In case the operation index is larger than the previous largest used index,
219+ /// it will fill any inbetween indexes with zeroes
221220 pub fn set ( & mut self , operation : usize , cost : & Int ) -> Result < Int , JsError > {
222- if operation >= COST_MODEL_OP_COUNT {
223- return Err ( JsError :: from_str ( & format ! ( "CostModel operation {} out of bounds. Max is {}" , operation, COST_MODEL_OP_COUNT ) ) ) ;
221+ let len = self . 0 . len ( ) ;
222+ let idx = operation. clone ( ) ;
223+ if idx >= len {
224+ for _ in 0 .. ( idx - len + 1 ) {
225+ self . 0 . push ( Int :: new_i32 ( 0 ) ) ;
226+ }
224227 }
225- let old = self . 0 [ operation ] . clone ( ) ;
226- self . 0 [ operation ] = cost. clone ( ) ;
228+ let old = self . 0 [ idx ] . clone ( ) ;
229+ self . 0 [ idx ] = cost. clone ( ) ;
227230 Ok ( old)
228231 }
229232
230233 pub fn get ( & self , operation : usize ) -> Result < Int , JsError > {
231- if operation >= COST_MODEL_OP_COUNT {
232- return Err ( JsError :: from_str ( & format ! ( "CostModel operation {} out of bounds. Max is {}" , operation, COST_MODEL_OP_COUNT ) ) ) ;
234+ let max = self . 0 . len ( ) ;
235+ if operation >= max {
236+ return Err ( JsError :: from_str ( & format ! ( "CostModel operation {} out of bounds. Max is {}" , operation, max) ) ) ;
233237 }
234238 Ok ( self . 0 [ operation] . clone ( ) )
235239 }
@@ -898,7 +902,7 @@ impl Deserialize for ConstrPlutusData {
898902
899903impl cbor_event:: se:: Serialize for CostModel {
900904 fn serialize < ' se , W : Write > ( & self , serializer : & ' se mut Serializer < W > ) -> cbor_event:: Result < & ' se mut Serializer < W > > {
901- serializer. write_array ( cbor_event:: Len :: Len ( COST_MODEL_OP_COUNT as u64 ) ) ?;
905+ serializer. write_array ( cbor_event:: Len :: Len ( self . 0 . len ( ) as u64 ) ) ?;
902906 for cost in & self . 0 {
903907 cost. serialize ( serializer) ?;
904908 }
@@ -918,13 +922,6 @@ impl Deserialize for CostModel {
918922 }
919923 arr. push ( Int :: deserialize ( raw) ?) ;
920924 }
921- if arr. len ( ) != COST_MODEL_OP_COUNT {
922- return Err ( DeserializeFailure :: OutOfRange {
923- min : COST_MODEL_OP_COUNT ,
924- max : COST_MODEL_OP_COUNT ,
925- found : arr. len ( )
926- } . into ( ) ) ;
927- }
928925 Ok ( ( ) )
929926 } ) ( ) . map_err ( |e| e. annotate ( "CostModel" ) ) ?;
930927 Ok ( Self ( arr. try_into ( ) . unwrap ( ) ) )
@@ -1574,4 +1571,11 @@ mod tests {
15741571 Language :: new_plutus_v2( ) ,
15751572 ) ;
15761573 }
1574+
1575+ #[ test]
1576+ fn test_cost_model_roundtrip ( ) {
1577+ use crate :: tx_builder_constants:: TxBuilderConstants ;
1578+ let costmodels = TxBuilderConstants :: plutus_vasil_cost_models ( ) ;
1579+ assert_eq ! ( costmodels, Costmdls :: from_bytes( costmodels. to_bytes( ) ) . unwrap( ) ) ;
1580+ }
15771581}
0 commit comments