-
Notifications
You must be signed in to change notification settings - Fork 55
/
CostModel.ts
161 lines (146 loc) · 5.02 KB
/
CostModel.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import * as Cardano from '../../../Cardano';
import { InvalidArgumentError, InvalidStateError } from '@cardano-sdk/util';
const PLUTUS_V1_COST_MODEL_OP_COUNT = 166;
const PLUTUS_V2_COST_MODEL_OP_COUNT = 175;
const PLUTUS_V3_COST_MODEL_OP_COUNT = 179;
/**
* The execution of plutus scripts consumes resources. To make sure that these
* scripts don't run indefinitely or consume excessive resources (which would be
* harmful to the network), Cardano introduces the concept of "cost models".
*
* Cost models are in place to provide predictable pricing for script execution.
*
* It's a way to gauge how much resource (in terms of computational steps or memory)
* a script would use.
*/
export class CostModel {
#language: Cardano.PlutusLanguageVersion;
#costs: Array<number>;
/**
* Initializes a new instance of the CostModel class.
*
* @param language The plutus language version.
* @param costs The costs.
*/
constructor(language: Cardano.PlutusLanguageVersion, costs: Array<number>) {
this.#language = language;
this.#costs = costs;
switch (this.#language) {
case Cardano.PlutusLanguageVersion.V1:
if (costs.length !== PLUTUS_V1_COST_MODEL_OP_COUNT)
throw new InvalidArgumentError(
'costs',
`Cost model for PlutusV2 language should have ${PLUTUS_V2_COST_MODEL_OP_COUNT} operations, but got ${costs.length}.`
);
break;
case Cardano.PlutusLanguageVersion.V2:
if (costs.length !== PLUTUS_V2_COST_MODEL_OP_COUNT)
throw new InvalidArgumentError(
'costs',
`Cost model for PlutusV2 language should have ${PLUTUS_V2_COST_MODEL_OP_COUNT} operations, but got ${costs.length}.`
);
break;
case Cardano.PlutusLanguageVersion.V3:
if (costs.length !== PLUTUS_V3_COST_MODEL_OP_COUNT)
throw new InvalidArgumentError(
'costs',
`Cost model for PlutusV3 language should have ${PLUTUS_V3_COST_MODEL_OP_COUNT} operations, but got ${costs.length}.`
);
break;
default:
throw new InvalidStateError('Invalid plutus language version.');
}
}
/**
* Creates a new Plutus V1 cost model.
*
* @param costs An array containing the costs for all operations.
*/
static newPlutusV1(costs: Array<number>): CostModel {
return new CostModel(Cardano.PlutusLanguageVersion.V1, costs);
}
/**
* Creates a new Plutus V2 cost model.
*
* @param costs An array containing the costs for all operations.
*/
static newPlutusV2(costs: Array<number>): CostModel {
return new CostModel(Cardano.PlutusLanguageVersion.V2, costs);
}
/**
* Creates a new Plutus V3 cost model.
*
* @param costs An array containing the costs for all operations.
*/
static newPlutusV3(costs: Array<number>): CostModel {
return new CostModel(Cardano.PlutusLanguageVersion.V3, costs);
}
/**
* Sets the cost for the given operation.
*
* @param operation The operation to get the cost for.
* @param cost The cost of the operation.
*/
set(operation: number, cost: number): void {
if (!this.#isOperationValid(operation))
throw new InvalidArgumentError(
'operation',
`The given operation ${operation} is invalid for the current Language version ${this.#language}.`
);
this.#costs[operation] = cost;
}
/**
* Gets the cost for the given operation.
*
* @param operation The operation to get the cost for.
* @returns The operation cost.
*/
get(operation: number): number {
if (!this.#isOperationValid(operation))
throw new InvalidArgumentError(
'operation',
`The given operation ${operation} is invalid for the current Language version ${this.#language}.`
);
return this.#costs[operation];
}
/**
* Gets the list of costs as a int array.
*
* @returns The list of costs, where the index on the array represents the operation id and the value
* the operation cost.
*/
costs(): Array<number> {
return this.#costs;
}
/**
* Gets the language version of this cost model.
*
* @returns The language version.
*/
language(): Cardano.PlutusLanguageVersion {
return this.#language;
}
/**
* Gets whether the given operation is valid for this Language version.
*
* @param operation The operation we are trying to validate.
* @returns true if is a valid operation; otherwise; false.
*/
#isOperationValid(operation: number): boolean {
let isValid = false;
switch (this.#language) {
case Cardano.PlutusLanguageVersion.V1:
isValid = operation >= 0 && operation < PLUTUS_V1_COST_MODEL_OP_COUNT;
break;
case Cardano.PlutusLanguageVersion.V2:
isValid = operation >= 0 && operation < PLUTUS_V2_COST_MODEL_OP_COUNT;
break;
case Cardano.PlutusLanguageVersion.V3:
isValid = operation >= 0 && operation < PLUTUS_V3_COST_MODEL_OP_COUNT;
break;
default:
throw new InvalidStateError('Invalid plutus language version.');
}
return isValid;
}
}