@@ -27,9 +27,7 @@ use polkadot_node_core_pvf::{
27
27
InternalValidationError , InvalidCandidate as WasmInvalidCandidate , PossiblyInvalidError ,
28
28
PrepareError , PrepareJobKind , PvfPrepData , ValidationError , ValidationHost ,
29
29
} ;
30
- use polkadot_node_primitives:: {
31
- BlockData , InvalidCandidate , PoV , ValidationResult , POV_BOMB_LIMIT , VALIDATION_CODE_BOMB_LIMIT ,
32
- } ;
30
+ use polkadot_node_primitives:: { InvalidCandidate , PoV , ValidationResult } ;
33
31
use polkadot_node_subsystem:: {
34
32
errors:: RuntimeApiError ,
35
33
messages:: {
@@ -41,9 +39,7 @@ use polkadot_node_subsystem::{
41
39
} ;
42
40
use polkadot_node_subsystem_util as util;
43
41
use polkadot_overseer:: ActiveLeavesUpdate ;
44
- use polkadot_parachain_primitives:: primitives:: {
45
- ValidationParams , ValidationResult as WasmValidationResult ,
46
- } ;
42
+ use polkadot_parachain_primitives:: primitives:: ValidationResult as WasmValidationResult ;
47
43
use polkadot_primitives:: {
48
44
executor_params:: {
49
45
DEFAULT_APPROVAL_EXECUTION_TIMEOUT , DEFAULT_BACKING_EXECUTION_TIMEOUT ,
@@ -504,21 +500,12 @@ where
504
500
continue ;
505
501
} ;
506
502
507
- let pvf = match sp_maybe_compressed_blob:: decompress (
508
- & validation_code. 0 ,
509
- VALIDATION_CODE_BOMB_LIMIT ,
510
- ) {
511
- Ok ( code) => PvfPrepData :: from_code (
512
- code. into_owned ( ) ,
513
- executor_params. clone ( ) ,
514
- timeout,
515
- PrepareJobKind :: Prechecking ,
516
- ) ,
517
- Err ( e) => {
518
- gum:: debug!( target: LOG_TARGET , err=?e, "cannot decompress validation code" ) ;
519
- continue
520
- } ,
521
- } ;
503
+ let pvf = PvfPrepData :: from_code (
504
+ validation_code. 0 ,
505
+ executor_params. clone ( ) ,
506
+ timeout,
507
+ PrepareJobKind :: Prechecking ,
508
+ ) ;
522
509
523
510
active_pvfs. push ( pvf) ;
524
511
processed_code_hashes. push ( code_hash) ;
@@ -651,21 +638,12 @@ where
651
638
652
639
let timeout = pvf_prep_timeout ( & executor_params, PvfPrepKind :: Precheck ) ;
653
640
654
- let pvf = match sp_maybe_compressed_blob:: decompress (
655
- & validation_code. 0 ,
656
- VALIDATION_CODE_BOMB_LIMIT ,
657
- ) {
658
- Ok ( code) => PvfPrepData :: from_code (
659
- code. into_owned ( ) ,
660
- executor_params,
661
- timeout,
662
- PrepareJobKind :: Prechecking ,
663
- ) ,
664
- Err ( e) => {
665
- gum:: debug!( target: LOG_TARGET , err=?e, "precheck: cannot decompress validation code" ) ;
666
- return PreCheckOutcome :: Invalid
667
- } ,
668
- } ;
641
+ let pvf = PvfPrepData :: from_code (
642
+ validation_code. 0 ,
643
+ executor_params,
644
+ timeout,
645
+ PrepareJobKind :: Prechecking ,
646
+ ) ;
669
647
670
648
match validation_backend. precheck_pvf ( pvf) . await {
671
649
Ok ( _) => PreCheckOutcome :: Valid ,
@@ -873,49 +851,15 @@ async fn validate_candidate_exhaustive(
873
851
return Ok ( ValidationResult :: Invalid ( e) )
874
852
}
875
853
876
- let raw_validation_code = match sp_maybe_compressed_blob:: decompress (
877
- & validation_code. 0 ,
878
- VALIDATION_CODE_BOMB_LIMIT ,
879
- ) {
880
- Ok ( code) => code,
881
- Err ( e) => {
882
- gum:: info!( target: LOG_TARGET , ?para_id, err=?e, "Invalid candidate (validation code)" ) ;
883
-
884
- // Code already passed pre-checking, if decompression fails now this most likely means
885
- // some local corruption happened.
886
- return Err ( ValidationFailed ( "Code decompression failed" . to_string ( ) ) )
887
- } ,
888
- } ;
889
- metrics. observe_code_size ( raw_validation_code. len ( ) ) ;
890
-
891
- metrics. observe_pov_size ( pov. block_data . 0 . len ( ) , true ) ;
892
- let raw_block_data =
893
- match sp_maybe_compressed_blob:: decompress ( & pov. block_data . 0 , POV_BOMB_LIMIT ) {
894
- Ok ( block_data) => BlockData ( block_data. to_vec ( ) ) ,
895
- Err ( e) => {
896
- gum:: info!( target: LOG_TARGET , ?para_id, err=?e, "Invalid candidate (PoV code)" ) ;
897
-
898
- // If the PoV is invalid, the candidate certainly is.
899
- return Ok ( ValidationResult :: Invalid ( InvalidCandidate :: PoVDecompressionFailure ) )
900
- } ,
901
- } ;
902
- metrics. observe_pov_size ( raw_block_data. 0 . len ( ) , false ) ;
903
-
904
- let params = ValidationParams {
905
- parent_head : persisted_validation_data. parent_head . clone ( ) ,
906
- block_data : raw_block_data,
907
- relay_parent_number : persisted_validation_data. relay_parent_number ,
908
- relay_parent_storage_root : persisted_validation_data. relay_parent_storage_root ,
909
- } ;
910
-
854
+ let persisted_validation_data = Arc :: new ( persisted_validation_data) ;
911
855
let result = match exec_kind {
912
856
// Retry is disabled to reduce the chance of nondeterministic blocks getting backed and
913
857
// honest backers getting slashed.
914
858
PvfExecKind :: Backing => {
915
859
let prep_timeout = pvf_prep_timeout ( & executor_params, PvfPrepKind :: Prepare ) ;
916
860
let exec_timeout = pvf_exec_timeout ( & executor_params, exec_kind) ;
917
861
let pvf = PvfPrepData :: from_code (
918
- raw_validation_code . to_vec ( ) ,
862
+ validation_code . 0 ,
919
863
executor_params,
920
864
prep_timeout,
921
865
PrepareJobKind :: Compilation ,
@@ -925,17 +869,19 @@ async fn validate_candidate_exhaustive(
925
869
. validate_candidate (
926
870
pvf,
927
871
exec_timeout,
928
- params. encode ( ) ,
872
+ persisted_validation_data. clone ( ) ,
873
+ pov,
929
874
polkadot_node_core_pvf:: Priority :: Normal ,
930
875
)
931
876
. await
932
877
} ,
933
878
PvfExecKind :: Approval =>
934
879
validation_backend
935
880
. validate_candidate_with_retry (
936
- raw_validation_code . to_vec ( ) ,
881
+ validation_code . 0 ,
937
882
pvf_exec_timeout ( & executor_params, exec_kind) ,
938
- params,
883
+ persisted_validation_data. clone ( ) ,
884
+ pov,
939
885
executor_params,
940
886
PVF_APPROVAL_EXECUTION_RETRY_DELAY ,
941
887
polkadot_node_core_pvf:: Priority :: Critical ,
@@ -961,6 +907,8 @@ async fn validate_candidate_exhaustive(
961
907
Ok ( ValidationResult :: Invalid ( InvalidCandidate :: Timeout ) ) ,
962
908
Err ( ValidationError :: Invalid ( WasmInvalidCandidate :: WorkerReportedInvalid ( e) ) ) =>
963
909
Ok ( ValidationResult :: Invalid ( InvalidCandidate :: ExecutionError ( e) ) ) ,
910
+ Err ( ValidationError :: Invalid ( WasmInvalidCandidate :: PoVDecompressionFailure ) ) =>
911
+ Ok ( ValidationResult :: Invalid ( InvalidCandidate :: PoVDecompressionFailure ) ) ,
964
912
Err ( ValidationError :: PossiblyInvalid ( PossiblyInvalidError :: AmbiguousWorkerDeath ) ) =>
965
913
Ok ( ValidationResult :: Invalid ( InvalidCandidate :: ExecutionError (
966
914
"ambiguous worker death" . to_string ( ) ,
@@ -1007,7 +955,7 @@ async fn validate_candidate_exhaustive(
1007
955
// invalid.
1008
956
Ok ( ValidationResult :: Invalid ( InvalidCandidate :: CommitmentsHashMismatch ) )
1009
957
} else {
1010
- Ok ( ValidationResult :: Valid ( outputs, persisted_validation_data) )
958
+ Ok ( ValidationResult :: Valid ( outputs, ( * persisted_validation_data) . clone ( ) ) )
1011
959
}
1012
960
} ,
1013
961
}
@@ -1020,7 +968,8 @@ trait ValidationBackend {
1020
968
& mut self ,
1021
969
pvf : PvfPrepData ,
1022
970
exec_timeout : Duration ,
1023
- encoded_params : Vec < u8 > ,
971
+ pvd : Arc < PersistedValidationData > ,
972
+ pov : Arc < PoV > ,
1024
973
// The priority for the preparation job.
1025
974
prepare_priority : polkadot_node_core_pvf:: Priority ,
1026
975
) -> Result < WasmValidationResult , ValidationError > ;
@@ -1035,9 +984,10 @@ trait ValidationBackend {
1035
984
/// preparation.
1036
985
async fn validate_candidate_with_retry (
1037
986
& mut self ,
1038
- raw_validation_code : Vec < u8 > ,
987
+ code : Vec < u8 > ,
1039
988
exec_timeout : Duration ,
1040
- params : ValidationParams ,
989
+ pvd : Arc < PersistedValidationData > ,
990
+ pov : Arc < PoV > ,
1041
991
executor_params : ExecutorParams ,
1042
992
retry_delay : Duration ,
1043
993
// The priority for the preparation job.
@@ -1046,7 +996,7 @@ trait ValidationBackend {
1046
996
let prep_timeout = pvf_prep_timeout ( & executor_params, PvfPrepKind :: Prepare ) ;
1047
997
// Construct the PVF a single time, since it is an expensive operation. Cloning it is cheap.
1048
998
let pvf = PvfPrepData :: from_code (
1049
- raw_validation_code ,
999
+ code ,
1050
1000
executor_params,
1051
1001
prep_timeout,
1052
1002
PrepareJobKind :: Compilation ,
@@ -1057,7 +1007,13 @@ trait ValidationBackend {
1057
1007
1058
1008
// Use `Priority::Critical` as finality trumps parachain liveliness.
1059
1009
let mut validation_result = self
1060
- . validate_candidate ( pvf. clone ( ) , exec_timeout, params. encode ( ) , prepare_priority)
1010
+ . validate_candidate (
1011
+ pvf. clone ( ) ,
1012
+ exec_timeout,
1013
+ pvd. clone ( ) ,
1014
+ pov. clone ( ) ,
1015
+ prepare_priority,
1016
+ )
1061
1017
. await ;
1062
1018
if validation_result. is_ok ( ) {
1063
1019
return validation_result
@@ -1130,10 +1086,14 @@ trait ValidationBackend {
1130
1086
validation_result
1131
1087
) ;
1132
1088
1133
- // Encode the params again when re-trying. We expect the retry case to be relatively
1134
- // rare, and we want to avoid unconditionally cloning data.
1135
1089
validation_result = self
1136
- . validate_candidate ( pvf. clone ( ) , new_timeout, params. encode ( ) , prepare_priority)
1090
+ . validate_candidate (
1091
+ pvf. clone ( ) ,
1092
+ new_timeout,
1093
+ pvd. clone ( ) ,
1094
+ pov. clone ( ) ,
1095
+ prepare_priority,
1096
+ )
1137
1097
. await ;
1138
1098
}
1139
1099
}
@@ -1153,13 +1113,13 @@ impl ValidationBackend for ValidationHost {
1153
1113
& mut self ,
1154
1114
pvf : PvfPrepData ,
1155
1115
exec_timeout : Duration ,
1156
- encoded_params : Vec < u8 > ,
1116
+ pvd : Arc < PersistedValidationData > ,
1117
+ pov : Arc < PoV > ,
1157
1118
// The priority for the preparation job.
1158
1119
prepare_priority : polkadot_node_core_pvf:: Priority ,
1159
1120
) -> Result < WasmValidationResult , ValidationError > {
1160
1121
let ( tx, rx) = oneshot:: channel ( ) ;
1161
- if let Err ( err) =
1162
- self . execute_pvf ( pvf, exec_timeout, encoded_params, prepare_priority, tx) . await
1122
+ if let Err ( err) = self . execute_pvf ( pvf, exec_timeout, pvd, pov, prepare_priority, tx) . await
1163
1123
{
1164
1124
return Err ( InternalValidationError :: HostCommunication ( format ! (
1165
1125
"cannot send pvf to the validation host, it might have shut down: {:?}" ,
0 commit comments