@@ -7,12 +7,13 @@ use crate::{
77 } ,
88 proposals:: {
99 decode_candid_args_to_self_describing_value:: decode_candid_args_to_self_describing_value,
10- self_describing:: ValueBuilder ,
10+ self_describing:: { SelfDescribingProstEnum , ValueBuilder } ,
1111 } ,
1212} ;
1313
1414use candid:: { Decode , Encode } ;
1515use ic_base_types:: CanisterId ;
16+ use ic_crypto_sha2:: Sha256 ;
1617use ic_management_canister_types_private:: { CanisterMetadataRequest , CanisterMetadataResponse } ;
1718use ic_nns_common:: types:: CallCanisterRequest ;
1819use ic_nns_constants:: {
@@ -22,7 +23,7 @@ use ic_nns_constants::{
2223} ;
2324use ic_nns_governance_api:: bitcoin:: { BitcoinNetwork , BitcoinSetConfigProposal } ;
2425use ic_nns_governance_api:: subnet_rental:: { SubnetRentalProposalPayload , SubnetRentalRequest } ;
25- use ic_sns_wasm:: pb:: v1:: { AddWasmRequest , SnsWasm } ;
26+ use ic_sns_wasm:: pb:: v1:: { AddWasmRequest , SnsCanisterType , SnsWasm } ;
2627use std:: sync:: Arc ;
2728
2829/// A partial Candid interface for the management canister (ic_00) that contains the necessary
@@ -67,6 +68,16 @@ impl ValidExecuteNnsFunction {
6768 let request = get_request_for_bitcoin_set_config ( & self . payload ) ?;
6869 return Ok ( SelfDescribingValue :: from ( request) ) ;
6970 }
71+ ValidNnsFunction :: SubnetRentalRequest => {
72+ let subnet_rental_request =
73+ decode_subnet_rental_request ( & self . payload ) . map_err ( |e| e. error_message ) ?;
74+ return Ok ( SelfDescribingValue :: from ( subnet_rental_request) ) ;
75+ }
76+ ValidNnsFunction :: AddSnsWasm => {
77+ let add_wasm_request =
78+ decode_add_wasm_request ( & self . payload ) . map_err ( |e| e. error_message ) ?;
79+ return Ok ( SelfDescribingValue :: from ( add_wasm_request) ) ;
80+ }
7081 _ => { }
7182 } ;
7283
@@ -142,39 +153,19 @@ impl ValidExecuteNnsFunction {
142153 Ok ( encoded_request)
143154 }
144155 ValidNnsFunction :: SubnetRentalRequest => {
145- // Decode the payload to `SubnetRentalRequest`.
146- let decoded_payload =
147- Decode ! ( [ decoder_config( ) ] ; & self . payload, SubnetRentalRequest ) . map_err (
148- |_| {
149- GovernanceError :: new_with_message (
150- ErrorType :: InvalidProposal ,
151- "Unable to decode SubnetRentalRequest proposal: {e}" ,
152- )
153- } ,
154- ) ?;
155-
156- // Convert the payload to `SubnetRentalProposalPayload`.
157- let SubnetRentalRequest {
158- user,
159- rental_condition_id,
160- } = decoded_payload;
161- let proposal_creation_time_seconds = proposal_timestamp_seconds;
162- let encoded_payload = Encode ! ( & SubnetRentalProposalPayload {
163- user,
164- rental_condition_id,
156+ let decoded_payload = decode_subnet_rental_request ( & self . payload ) ?;
157+ let encoded_payload = encode_subnet_rental_proposal_payload (
158+ decoded_payload,
165159 proposal_id,
166- proposal_creation_time_seconds,
167- } )
168- . unwrap ( ) ;
169-
160+ proposal_timestamp_seconds,
161+ ) ?;
170162 Ok ( encoded_payload)
171163 }
172164
173165 ValidNnsFunction :: AddSnsWasm => {
174- let transformed_payload =
175- add_proposal_id_to_add_wasm_request ( & self . payload , proposal_id) ?;
176-
177- Ok ( transformed_payload)
166+ let decoded_payload = decode_add_wasm_request ( & self . payload ) ?;
167+ let encoded_payload = encode_add_wasm_request ( decoded_payload, proposal_id) ?;
168+ Ok ( encoded_payload)
178169 }
179170
180171 // Most NNS functions don't require any transformation of the payload, and for new NNS
@@ -203,35 +194,54 @@ fn get_request_for_bitcoin_set_config(payload: &[u8]) -> Result<CallCanisterRequ
203194 } )
204195}
205196
206- impl From < CallCanisterRequest > for SelfDescribingValue {
207- fn from ( request : CallCanisterRequest ) -> Self {
208- let CallCanisterRequest {
209- canister_id,
210- method_name,
211- payload,
212- } = request;
213- ValueBuilder :: new ( )
214- . add_field ( "canister_id" , canister_id)
215- . add_field ( "method_name" , method_name)
216- . add_field ( "payload" , payload)
217- . build ( )
218- }
197+ fn decode_subnet_rental_request ( payload : & [ u8 ] ) -> Result < SubnetRentalRequest , GovernanceError > {
198+ Decode ! ( [ decoder_config( ) ] ; payload, SubnetRentalRequest ) . map_err ( |_| {
199+ GovernanceError :: new_with_message (
200+ ErrorType :: InvalidProposal ,
201+ "Unable to decode SubnetRentalRequest proposal: {e}" ,
202+ )
203+ } )
219204}
220205
221- fn add_proposal_id_to_add_wasm_request (
222- payload : & [ u8 ] ,
206+ fn encode_subnet_rental_proposal_payload (
207+ subnet_rental_request : SubnetRentalRequest ,
223208 proposal_id : u64 ,
209+ proposal_creation_time_seconds : u64 ,
224210) -> Result < Vec < u8 > , GovernanceError > {
225- let add_wasm_request = match Decode ! ( [ decoder_config( ) ] ; payload, AddWasmRequest ) {
226- Ok ( add_wasm_request) => add_wasm_request,
227- Err ( e) => {
228- return Err ( GovernanceError :: new_with_message (
229- ErrorType :: InvalidProposal ,
230- format ! ( "Payload must be a valid AddWasmRequest. Error: {e}" ) ,
231- ) ) ;
232- }
233- } ;
211+ let SubnetRentalRequest {
212+ user,
213+ rental_condition_id,
214+ } = subnet_rental_request;
215+
216+ let encoded_payload = Encode ! ( & SubnetRentalProposalPayload {
217+ user,
218+ rental_condition_id,
219+ proposal_id,
220+ proposal_creation_time_seconds,
221+ } )
222+ . map_err ( |_| {
223+ GovernanceError :: new_with_message (
224+ ErrorType :: InvalidProposal ,
225+ "Unable to encode SubnetRentalProposalPayload proposal: {e}" ,
226+ )
227+ } ) ?;
228+
229+ Ok ( encoded_payload)
230+ }
234231
232+ fn decode_add_wasm_request ( payload : & [ u8 ] ) -> Result < AddWasmRequest , GovernanceError > {
233+ Decode ! ( [ decoder_config( ) ] ; payload, AddWasmRequest ) . map_err ( |_| {
234+ GovernanceError :: new_with_message (
235+ ErrorType :: InvalidProposal ,
236+ "Unable to decode AddWasmRequest proposal: {e}" ,
237+ )
238+ } )
239+ }
240+
241+ fn encode_add_wasm_request (
242+ add_wasm_request : AddWasmRequest ,
243+ proposal_id : u64 ,
244+ ) -> Result < Vec < u8 > , GovernanceError > {
235245 let wasm = add_wasm_request
236246 . wasm
237247 . ok_or ( GovernanceError :: new_with_message (
@@ -247,9 +257,74 @@ fn add_proposal_id_to_add_wasm_request(
247257 ..add_wasm_request
248258 } ;
249259
250- let payload = Encode ! ( & add_wasm_request) . unwrap ( ) ;
260+ Encode ! ( & add_wasm_request) . map_err ( |_| {
261+ GovernanceError :: new_with_message (
262+ ErrorType :: InvalidProposal ,
263+ "Unable to encode AddWasmRequest proposal: {e}" ,
264+ )
265+ } )
266+ }
251267
252- Ok ( payload)
268+ impl From < CallCanisterRequest > for SelfDescribingValue {
269+ fn from ( request : CallCanisterRequest ) -> Self {
270+ let CallCanisterRequest {
271+ canister_id,
272+ method_name,
273+ payload,
274+ } = request;
275+ ValueBuilder :: new ( )
276+ . add_field ( "canister_id" , canister_id)
277+ . add_field ( "method_name" , method_name)
278+ . add_field ( "payload" , payload)
279+ . build ( )
280+ }
281+ }
282+
283+ impl From < SubnetRentalRequest > for SelfDescribingValue {
284+ fn from ( request : SubnetRentalRequest ) -> Self {
285+ let SubnetRentalRequest {
286+ user,
287+ rental_condition_id,
288+ } = request;
289+ ValueBuilder :: new ( )
290+ . add_field ( "user" , user)
291+ . add_field ( "rental_condition_id" , format ! ( "{:?}" , rental_condition_id) )
292+ . build ( )
293+ }
294+ }
295+
296+ impl From < AddWasmRequest > for SelfDescribingValue {
297+ fn from ( payload : AddWasmRequest ) -> Self {
298+ let AddWasmRequest {
299+ wasm,
300+ hash,
301+ skip_update_latest_version,
302+ } = payload;
303+
304+ ValueBuilder :: new ( )
305+ . add_field ( "wasm" , wasm)
306+ . add_field ( "hash" , hash)
307+ . add_field ( "skip_update_latest_version" , skip_update_latest_version)
308+ . build ( )
309+ }
310+ }
311+
312+ impl From < SnsWasm > for SelfDescribingValue {
313+ fn from ( wasm : SnsWasm ) -> Self {
314+ let SnsWasm {
315+ wasm,
316+ canister_type,
317+ proposal_id : _,
318+ } = wasm;
319+
320+ let wasm_hash = Sha256 :: hash ( & wasm) . to_vec ( ) ;
321+ let canister_type = SelfDescribingProstEnum :: < SnsCanisterType > :: new ( canister_type) ;
322+
323+ ValueBuilder :: new ( )
324+ . add_field ( "wasm_hash" , wasm_hash)
325+ . add_field ( "canister_type" , canister_type)
326+ . build ( )
327+ }
253328}
254329
255330#[ derive( Debug , Clone , PartialEq ) ]
0 commit comments