@@ -53,29 +53,52 @@ impl<T: Config> Contract<T> {
53
53
seconds_elapsed : u64 ,
54
54
) -> Result < u64 , DispatchErrorWithPostInfo > {
55
55
let total_cost = match & self . contract_type {
56
- types:: ContractData :: CapacityReservationContract ( capacity_reservation_contract) => {
56
+ // Calculate total cost for a node contract
57
+ types:: ContractData :: NodeContract ( node_contract) => {
57
58
// Get the contract billing info to view the amount unbilled for NRU (network resource units)
58
59
let contract_billing_info = self . get_billing_info ( ) ;
59
60
// Get the node
60
- let node = pallet_tfgrid:: Nodes :: < T > :: get ( capacity_reservation_contract. node_id )
61
- . ok_or ( Error :: < T > :: NodeNotExists ) ?;
61
+ if !pallet_tfgrid:: Nodes :: < T > :: contains_key ( node_contract. node_id ) {
62
+ return Err ( DispatchErrorWithPostInfo :: from ( Error :: < T > :: NodeNotExists ) ) ;
63
+ }
64
+
65
+ // We know the contract is using resources, now calculate the cost for each used resource
66
+
67
+ let node_contract_resources =
68
+ pallet:: Pallet :: < T > :: node_contract_resources ( self . contract_id ) ;
69
+
70
+ let mut bill_resources = true ;
71
+ // If this node contract is deployed on a node which has a rent contract
72
+ // We can ignore billing for the resources used by this node contract
73
+ if pallet:: ActiveRentContractForNode :: < T > :: contains_key ( node_contract. node_id ) {
74
+ bill_resources = false
75
+ }
62
76
63
77
let contract_cost = calculate_resources_cost :: < T > (
64
- & capacity_reservation_contract . resources . total_resources ,
65
- capacity_reservation_contract . public_ips ,
78
+ node_contract_resources . used ,
79
+ node_contract . public_ips ,
66
80
seconds_elapsed,
67
81
& pricing_policy,
82
+ bill_resources,
68
83
) ;
69
- if node. resources . total_resources
70
- == capacity_reservation_contract. resources . total_resources
71
- {
72
- Percent :: from_percent ( pricing_policy. discount_for_dedication_nodes )
73
- * contract_cost
74
- + contract_billing_info. amount_unbilled
75
- } else {
76
- contract_cost + contract_billing_info. amount_unbilled
84
+ contract_cost + contract_billing_info. amount_unbilled
85
+ }
86
+ types:: ContractData :: RentContract ( rent_contract) => {
87
+ if !pallet_tfgrid:: Nodes :: < T > :: contains_key ( rent_contract. node_id ) {
88
+ return Err ( DispatchErrorWithPostInfo :: from ( Error :: < T > :: NodeNotExists ) ) ;
77
89
}
90
+ let node = pallet_tfgrid:: Nodes :: < T > :: get ( rent_contract. node_id ) . unwrap ( ) ;
91
+
92
+ let contract_cost = calculate_resources_cost :: < T > (
93
+ node. resources ,
94
+ 0 ,
95
+ seconds_elapsed,
96
+ & pricing_policy,
97
+ true ,
98
+ ) ;
99
+ Percent :: from_percent ( pricing_policy. discount_for_dedication_nodes ) * contract_cost
78
100
}
101
+ // Calculate total cost for a name contract
79
102
types:: ContractData :: NameContract ( _) => {
80
103
// bill user for name usage for number of seconds elapsed
81
104
let total_cost_u64f64 = ( U64F64 :: from_num ( pricing_policy. unique_name . value ) / 3600 )
@@ -90,30 +113,36 @@ impl<T: Config> Contract<T> {
90
113
91
114
// Calculates the total cost of a node contract.
92
115
pub fn calculate_resources_cost < T : Config > (
93
- resources : & Resources ,
116
+ resources : Resources ,
94
117
ipu : u32 ,
95
118
seconds_elapsed : u64 ,
96
119
pricing_policy : & pallet_tfgrid_types:: PricingPolicy < T :: AccountId > ,
120
+ bill_resources : bool ,
97
121
) -> u64 {
98
- let hru = U64F64 :: from_num ( resources. hru ) / pricing_policy. su . factor_base_1024 ( ) ;
99
- let sru = U64F64 :: from_num ( resources. sru ) / pricing_policy. su . factor_base_1024 ( ) ;
100
- let mru = U64F64 :: from_num ( resources. mru ) / pricing_policy. cu . factor_base_1024 ( ) ;
101
- let cru = U64F64 :: from_num ( resources. cru ) ;
102
-
103
- let su_used = hru / 1200 + sru / 200 ;
104
- // the pricing policy su cost value is expressed in 1 hours or 3600 seconds.
105
- // we bill every 3600 seconds but here we need to calculate the cost per second and multiply it by the seconds elapsed.
106
- let su_cost = ( U64F64 :: from_num ( pricing_policy. su . value ) / 3600 )
107
- * U64F64 :: from_num ( seconds_elapsed)
108
- * su_used;
109
- log:: debug!( "su cost: {:?}" , su_cost) ;
110
-
111
- let cu = calculate_cu ( cru, mru) ;
112
-
113
- let cu_cost =
114
- ( U64F64 :: from_num ( pricing_policy. cu . value ) / 3600 ) * U64F64 :: from_num ( seconds_elapsed) * cu;
115
- log:: debug!( "cu cost: {:?}" , cu_cost) ;
116
- let mut total_cost = su_cost + cu_cost;
122
+ let mut total_cost = U64F64 :: from_num ( 0 ) ;
123
+
124
+ if bill_resources {
125
+ let hru = U64F64 :: from_num ( resources. hru ) / pricing_policy. su . factor_base_1024 ( ) ;
126
+ let sru = U64F64 :: from_num ( resources. sru ) / pricing_policy. su . factor_base_1024 ( ) ;
127
+ let mru = U64F64 :: from_num ( resources. mru ) / pricing_policy. cu . factor_base_1024 ( ) ;
128
+ let cru = U64F64 :: from_num ( resources. cru ) ;
129
+
130
+ let su_used = hru / 1200 + sru / 200 ;
131
+ // the pricing policy su cost value is expressed in 1 hours or 3600 seconds.
132
+ // we bill every 3600 seconds but here we need to calculate the cost per second and multiply it by the seconds elapsed.
133
+ let su_cost = ( U64F64 :: from_num ( pricing_policy. su . value ) / 3600 )
134
+ * U64F64 :: from_num ( seconds_elapsed)
135
+ * su_used;
136
+ log:: debug!( "su cost: {:?}" , su_cost) ;
137
+
138
+ let cu = calculate_cu ( cru, mru) ;
139
+
140
+ let cu_cost = ( U64F64 :: from_num ( pricing_policy. cu . value ) / 3600 )
141
+ * U64F64 :: from_num ( seconds_elapsed)
142
+ * cu;
143
+ log:: debug!( "cu cost: {:?}" , cu_cost) ;
144
+ total_cost = su_cost + cu_cost;
145
+ }
117
146
118
147
if ipu > 0 {
119
148
let total_ip_cost = U64F64 :: from_num ( ipu)
0 commit comments