11use std:: collections:: BTreeMap ;
22
3+ use anyhow:: Context ;
4+ use base64:: prelude:: * ;
35use oasis_runtime_sdk:: {
6+ core:: {
7+ common:: crypto:: signature:: SignatureBundle ,
8+ consensus:: registry:: EndorsedCapabilityTEE ,
9+ host:: attestation:: { LabelAttestation , ATTEST_LABELS_SIGNATURE_CONTEXT } ,
10+ } ,
11+ crypto:: signature:: Signer ,
412 module,
513 modules:: {
614 accounts:: { self , API as _} ,
7- core, rofl,
15+ core,
16+ rofl:: {
17+ self ,
18+ policy:: { BasicEndorsementPolicyEvaluator , EndorsementPolicyEvaluator } ,
19+ } ,
820 } ,
921 testing:: { keys, mock} ,
1022 types:: {
@@ -14,7 +26,7 @@ use oasis_runtime_sdk::{
1426 Runtime , Version ,
1527} ;
1628
17- use super :: { types, ADDRESS_PROVIDER_STAKE_POOL } ;
29+ use super :: { policy , state , types, ADDRESS_PROVIDER_STAKE_POOL } ;
1830
1931type Accounts = accounts:: Module ;
2032type Core = core:: Module < Config > ;
@@ -23,7 +35,9 @@ struct Config;
2335
2436impl core:: Config for Config { }
2537
26- impl rofl:: Config for Config { }
38+ impl rofl:: Config for Config {
39+ type EndorsementPolicyEvaluator = BasicEndorsementPolicyEvaluator ;
40+ }
2741
2842impl super :: Config for Config {
2943 type Rofl = rofl:: Module < Config > ;
@@ -1032,3 +1046,159 @@ fn test_instance_accept_timeout() {
10321046 let balance = Accounts :: get_balance ( keys:: charlie:: address ( ) , Denomination :: NATIVE ) . unwrap ( ) ;
10331047 assert_eq ! ( balance, 1_000_000 ) ;
10341048}
1049+
1050+ #[ test]
1051+ fn test_endorsement_policy_evaluator ( ) {
1052+ let mut mock = mock:: Mock :: default ( ) ;
1053+ let ctx = mock. create_ctx_for_runtime :: < TestRuntime > ( true ) ;
1054+
1055+ TestRuntime :: migrate ( & ctx) ;
1056+
1057+ // Summary of keys used for this test:
1058+ //
1059+ // alice: provider
1060+ // bob: provider's node and scheduler's RAK
1061+ //
1062+
1063+ // Create the scheduler app.
1064+ let create = rofl:: types:: Create {
1065+ scheme : rofl:: types:: IdentifierScheme :: CreatorNonce ,
1066+ ..Default :: default ( )
1067+ } ;
1068+
1069+ let mut signer_alice = mock:: Signer :: new ( 0 , keys:: alice:: sigspec ( ) ) ;
1070+ let dispatch_result = signer_alice. call ( & ctx, "rofl.Create" , create) ;
1071+ assert ! ( dispatch_result. result. is_success( ) , "call should succeed" ) ;
1072+ let scheduler_app: rofl:: app_id:: AppId =
1073+ cbor:: from_value ( dispatch_result. result . unwrap ( ) ) . unwrap ( ) ;
1074+
1075+ // Create a provider.
1076+ let create = types:: ProviderCreate {
1077+ scheduler_app,
1078+ nodes : vec ! [ keys:: bob:: pk_ed25519( ) . into( ) ] , // Bob seems like a nice node.
1079+ ..Default :: default ( )
1080+ } ;
1081+
1082+ let dispatch_result = signer_alice. call ( & ctx, "roflmarket.ProviderCreate" , create. clone ( ) ) ;
1083+ assert ! ( dispatch_result. result. is_success( ) , "call should succeed" ) ;
1084+
1085+ // Create a mock instance of the scheduler app.
1086+ let fake_registration = rofl:: types:: Registration {
1087+ app : scheduler_app,
1088+ node_id : keys:: bob:: pk_ed25519 ( ) . into ( ) , // Bob is a nice approved node.
1089+ rak : keys:: bob:: pk_ed25519 ( ) . into ( ) , // Bob is also a nice RAK.
1090+ ..Default :: default ( )
1091+ } ;
1092+ rofl:: state:: update_registration ( fake_registration) . unwrap ( ) ;
1093+
1094+ // Create a new accepted instance directly in state.
1095+ let accepted_instance = types:: Instance {
1096+ provider : keys:: alice:: address ( ) ,
1097+ status : types:: InstanceStatus :: Accepted ,
1098+ node_id : Some ( keys:: bob:: pk_ed25519 ( ) . into ( ) ) ,
1099+ admin : keys:: charlie:: address ( ) ,
1100+ ..Default :: default ( )
1101+ } ;
1102+ state:: set_instance ( accepted_instance. clone ( ) ) ;
1103+
1104+ // Construct a composite endorsement policy evaluator.
1105+ type Evaluator = (
1106+ rofl:: policy:: BasicEndorsementPolicyEvaluator ,
1107+ super :: policy:: ProviderEndorsementPolicyEvaluator ,
1108+ ) ;
1109+
1110+ // Mock an endorsed TEE with attested labels.
1111+ let ect = EndorsedCapabilityTEE {
1112+ node_endorsement : SignatureBundle {
1113+ public_key : keys:: bob:: pk_ed25519 ( ) . into ( ) ,
1114+ ..Default :: default ( )
1115+ } ,
1116+ ..Default :: default ( )
1117+ } ;
1118+ let provider_label = policy:: ProviderLabel {
1119+ provider : keys:: alice:: address ( ) ,
1120+ instance : accepted_instance. id ,
1121+ } ;
1122+ let label_attestation = cbor:: to_vec ( LabelAttestation {
1123+ labels : BTreeMap :: from ( [ (
1124+ policy:: LABEL_PROVIDER . to_string ( ) ,
1125+ BASE64_STANDARD . encode ( cbor:: to_vec ( provider_label) ) ,
1126+ ) ] ) ,
1127+ rak : ect. capability_tee . rak ,
1128+ } ) ;
1129+ let signature = keys:: bob:: signer ( )
1130+ . sign ( ATTEST_LABELS_SIGNATURE_CONTEXT , & label_attestation)
1131+ . unwrap ( ) ;
1132+ let provider_attestation = policy:: ProviderAttestation {
1133+ label_attestation,
1134+ signature : signature. into ( ) ,
1135+ } ;
1136+ let metadata = BTreeMap :: from ( [ (
1137+ policy:: METADATA_KEY_POLICY_PROVIDER_ATTESTATION . to_string ( ) ,
1138+ BASE64_STANDARD . encode ( cbor:: to_vec ( provider_attestation) ) ,
1139+ ) ] ) ;
1140+
1141+ let tcs = [
1142+ (
1143+ vec ! [ Box :: new( rofl:: policy:: AllowedEndorsement :: Provider (
1144+ keys:: alice:: address( ) ,
1145+ ) ) ] ,
1146+ true ,
1147+ ) ,
1148+ (
1149+ vec ! [ Box :: new( rofl:: policy:: AllowedEndorsement :: And ( vec![
1150+ Box :: new( rofl:: policy:: AllowedEndorsement :: Provider (
1151+ keys:: alice:: address( ) ,
1152+ ) ) ,
1153+ Box :: new( rofl:: policy:: AllowedEndorsement :: Node (
1154+ keys:: bob:: pk_ed25519( ) . into( ) ,
1155+ ) ) ,
1156+ ] ) ) ] ,
1157+ true ,
1158+ ) ,
1159+ (
1160+ vec ! [ Box :: new(
1161+ rofl:: policy:: AllowedEndorsement :: ProviderInstanceAdmin ( keys:: charlie:: address( ) ) ,
1162+ ) ] ,
1163+ true ,
1164+ ) ,
1165+ (
1166+ vec ! [ Box :: new(
1167+ rofl:: policy:: AllowedEndorsement :: ProviderInstanceAdmin ( keys:: dave:: address( ) ) ,
1168+ ) ] ,
1169+ false ,
1170+ ) ,
1171+ (
1172+ vec ! [ Box :: new( rofl:: policy:: AllowedEndorsement :: Provider (
1173+ keys:: bob:: address( ) ,
1174+ ) ) ] ,
1175+ false ,
1176+ ) ,
1177+ (
1178+ vec ! [ Box :: new( rofl:: policy:: AllowedEndorsement :: Provider (
1179+ keys:: charlie:: address( ) ,
1180+ ) ) ] ,
1181+ false ,
1182+ ) ,
1183+ (
1184+ vec ! [ Box :: new( rofl:: policy:: AllowedEndorsement :: And ( vec![
1185+ Box :: new( rofl:: policy:: AllowedEndorsement :: Provider (
1186+ keys:: alice:: address( ) ,
1187+ ) ) ,
1188+ Box :: new( rofl:: policy:: AllowedEndorsement :: Node (
1189+ keys:: charlie:: pk_ed25519( ) . into( ) ,
1190+ ) ) ,
1191+ ] ) ) ] ,
1192+ false ,
1193+ ) ,
1194+ ] ;
1195+
1196+ for ( idx, tc) in tcs. iter ( ) . enumerate ( ) {
1197+ let result = Evaluator :: verify ( & ctx, & tc. 0 , & ect, & metadata) ;
1198+ if tc. 1 {
1199+ result. context ( format ! ( "test case {}" , idx) ) . unwrap ( ) ;
1200+ } else {
1201+ result. unwrap_err ( ) ;
1202+ }
1203+ }
1204+ }
0 commit comments