@@ -24,12 +24,12 @@ use ic_crypto_tecdsa::derive_tecdsa_public_key;
24
24
use ic_cycles_account_manager:: { CyclesAccountManager , IngressInductionCost } ;
25
25
use ic_error_types:: { ErrorCode , RejectCode , UserError } ;
26
26
use ic_ic00_types:: {
27
- CanisterChangeOrigin , CanisterHttpRequestArgs , CanisterIdRecord , CanisterSettingsArgs ,
28
- ComputeInitialEcdsaDealingsArgs , CreateCanisterArgs , ECDSAPublicKeyArgs ,
29
- ECDSAPublicKeyResponse , EcdsaKeyId , EmptyBlob , InstallCodeArgs , Method as Ic00Method ,
30
- Payload as Ic00Payload , ProvisionalCreateCanisterWithCyclesArgs , ProvisionalTopUpCanisterArgs ,
31
- SetControllerArgs , SetupInitialDKGArgs , SignWithECDSAArgs , UninstallCodeArgs ,
32
- UpdateSettingsArgs , IC_00 ,
27
+ CanisterChangeOrigin , CanisterHttpRequestArgs , CanisterIdRecord , CanisterInfoRequest ,
28
+ CanisterInfoResponse , CanisterSettingsArgs , ComputeInitialEcdsaDealingsArgs ,
29
+ CreateCanisterArgs , ECDSAPublicKeyArgs , ECDSAPublicKeyResponse , EcdsaKeyId , EmptyBlob ,
30
+ InstallCodeArgs , Method as Ic00Method , Payload as Ic00Payload ,
31
+ ProvisionalCreateCanisterWithCyclesArgs , ProvisionalTopUpCanisterArgs , SetControllerArgs ,
32
+ SetupInitialDKGArgs , SignWithECDSAArgs , UninstallCodeArgs , UpdateSettingsArgs , IC_00 ,
33
33
} ;
34
34
use ic_interfaces:: {
35
35
execution_environment:: {
@@ -657,6 +657,23 @@ impl ExecutionEnvironment {
657
657
Some ( ( res, msg. take_cycles ( ) ) )
658
658
}
659
659
660
+ Ok ( Ic00Method :: CanisterInfo ) => match & msg {
661
+ CanisterCall :: Request ( _) => {
662
+ let res = match CanisterInfoRequest :: decode ( payload) {
663
+ Err ( err) => Err ( err) ,
664
+ Ok ( record) => self . get_canister_info (
665
+ record. canister_id ( ) ,
666
+ record. num_requested_changes ( ) ,
667
+ & state,
668
+ ) ,
669
+ } ;
670
+ Some ( ( res, msg. take_cycles ( ) ) )
671
+ }
672
+ CanisterCall :: Ingress ( _) => {
673
+ self . reject_unexpected_ingress ( Ic00Method :: CanisterInfo )
674
+ }
675
+ } ,
676
+
660
677
Ok ( Ic00Method :: StartCanister ) => {
661
678
let res = match CanisterIdRecord :: decode ( payload) {
662
679
Err ( err) => Err ( err) ,
@@ -1354,6 +1371,32 @@ impl ExecutionEnvironment {
1354
1371
. map_err ( |err| err. into ( ) )
1355
1372
}
1356
1373
1374
+ fn get_canister_info (
1375
+ & self ,
1376
+ canister_id : CanisterId ,
1377
+ num_requested_changes : Option < u64 > ,
1378
+ state : & ReplicatedState ,
1379
+ ) -> Result < Vec < u8 > , UserError > {
1380
+ let canister = get_canister ( canister_id, state) ?;
1381
+ let canister_history = canister. system_state . get_canister_history ( ) ;
1382
+ let total_num_changes = canister_history. get_total_num_changes ( ) ;
1383
+ let changes = canister_history
1384
+ . get_changes ( num_requested_changes. unwrap_or ( 0 ) as usize )
1385
+ . map ( |e| ( * e. clone ( ) ) . clone ( ) )
1386
+ . collect ( ) ;
1387
+ let module_hash = canister
1388
+ . execution_state
1389
+ . as_ref ( )
1390
+ . map ( |es| es. wasm_binary . binary . module_hash ( ) . to_vec ( ) ) ;
1391
+ let controllers = canister
1392
+ . controllers ( )
1393
+ . iter ( )
1394
+ . copied ( )
1395
+ . collect :: < Vec < PrincipalId > > ( ) ;
1396
+ let res = CanisterInfoResponse :: new ( total_num_changes, changes, module_hash, controllers) ;
1397
+ Ok ( res. encode ( ) )
1398
+ }
1399
+
1357
1400
fn stop_canister (
1358
1401
& self ,
1359
1402
canister_id : CanisterId ,
@@ -2335,6 +2378,19 @@ pub(crate) fn subnet_memory_capacity(config: &ExecutionConfig) -> SubnetAvailabl
2335
2378
)
2336
2379
}
2337
2380
2381
+ fn get_canister (
2382
+ canister_id : CanisterId ,
2383
+ state : & ReplicatedState ,
2384
+ ) -> Result < & CanisterState , UserError > {
2385
+ match state. canister_state ( & canister_id) {
2386
+ Some ( canister) => Ok ( canister) ,
2387
+ None => Err ( UserError :: new (
2388
+ ErrorCode :: CanisterNotFound ,
2389
+ format ! ( "Canister {} not found." , & canister_id) ,
2390
+ ) ) ,
2391
+ }
2392
+ }
2393
+
2338
2394
fn get_canister_mut (
2339
2395
canister_id : CanisterId ,
2340
2396
state : & mut ReplicatedState ,
0 commit comments