@@ -89,6 +89,7 @@ const INV_REWARD_CYCLES_TESTNET: u64 = 6;
89
89
const DEFAULT_MIN_TIME_BETWEEN_BLOCKS_MS : u64 = 1000 ;
90
90
91
91
#[ derive( Clone , Deserialize , Default , Debug ) ]
92
+ #[ serde( deny_unknown_fields) ]
92
93
pub struct ConfigFile {
93
94
pub __path : Option < String > , // Only used for config file reloads
94
95
pub burnchain : Option < BurnchainConfigFile > ,
@@ -1318,6 +1319,7 @@ pub struct AffirmationOverride {
1318
1319
}
1319
1320
1320
1321
#[ derive( Clone , Deserialize , Default , Debug ) ]
1322
+ #[ serde( deny_unknown_fields) ]
1321
1323
pub struct BurnchainConfigFile {
1322
1324
pub chain : Option < String > ,
1323
1325
pub mode : Option < String > ,
@@ -2200,6 +2202,7 @@ impl Default for MinerConfig {
2200
2202
}
2201
2203
2202
2204
#[ derive( Clone , Default , Deserialize , Debug ) ]
2205
+ #[ serde( deny_unknown_fields) ]
2203
2206
pub struct ConnectionOptionsFile {
2204
2207
pub inbox_maxlen : Option < usize > ,
2205
2208
pub outbox_maxlen : Option < usize > ,
@@ -2383,6 +2386,7 @@ impl ConnectionOptionsFile {
2383
2386
}
2384
2387
2385
2388
#[ derive( Clone , Deserialize , Default , Debug ) ]
2389
+ #[ serde( deny_unknown_fields) ]
2386
2390
pub struct NodeConfigFile {
2387
2391
pub name : Option < String > ,
2388
2392
pub seed : Option < String > ,
@@ -2517,6 +2521,7 @@ impl NodeConfigFile {
2517
2521
}
2518
2522
2519
2523
#[ derive( Clone , Deserialize , Default , Debug ) ]
2524
+ #[ serde( deny_unknown_fields) ]
2520
2525
pub struct FeeEstimationConfigFile {
2521
2526
pub cost_estimator : Option < String > ,
2522
2527
pub fee_estimator : Option < String > ,
@@ -2528,6 +2533,7 @@ pub struct FeeEstimationConfigFile {
2528
2533
}
2529
2534
2530
2535
#[ derive( Clone , Deserialize , Default , Debug ) ]
2536
+ #[ serde( deny_unknown_fields) ]
2531
2537
pub struct MinerConfigFile {
2532
2538
pub first_attempt_time_ms : Option < u64 > ,
2533
2539
pub subsequent_attempt_time_ms : Option < u64 > ,
@@ -2670,6 +2676,7 @@ impl MinerConfigFile {
2670
2676
}
2671
2677
}
2672
2678
#[ derive( Clone , Deserialize , Default , Debug ) ]
2679
+ #[ serde( deny_unknown_fields) ]
2673
2680
pub struct AtlasConfigFile {
2674
2681
pub attachments_max_size : Option < u32 > ,
2675
2682
pub max_uninstantiated_attachments : Option < u32 > ,
@@ -2698,6 +2705,7 @@ impl AtlasConfigFile {
2698
2705
}
2699
2706
2700
2707
#[ derive( Clone , Deserialize , Default , Debug , Hash , PartialEq , Eq , PartialOrd ) ]
2708
+ #[ serde( deny_unknown_fields) ]
2701
2709
pub struct EventObserverConfigFile {
2702
2710
pub endpoint : String ,
2703
2711
pub events_keys : Vec < String > ,
@@ -2798,6 +2806,7 @@ pub struct InitialBalance {
2798
2806
}
2799
2807
2800
2808
#[ derive( Clone , Deserialize , Default , Debug ) ]
2809
+ #[ serde( deny_unknown_fields) ]
2801
2810
pub struct InitialBalanceFile {
2802
2811
pub address : String ,
2803
2812
pub amount : u64 ,
@@ -2873,6 +2882,124 @@ mod tests {
2873
2882
assert ! ( Config :: from_config_file( ConfigFile :: from_str( "" ) . unwrap( ) , false ) . is_ok( ) ) ;
2874
2883
}
2875
2884
2885
+ #[ test]
2886
+ fn test_deny_unknown_fields ( ) {
2887
+ {
2888
+ let err = ConfigFile :: from_str (
2889
+ r#"
2890
+ [node]
2891
+ name = "test"
2892
+ unknown_field = "test"
2893
+ "# ,
2894
+ )
2895
+ . unwrap_err ( ) ;
2896
+ assert ! ( err. starts_with( "Invalid toml: unknown field `unknown_field`" ) ) ;
2897
+ }
2898
+
2899
+ {
2900
+ let err = ConfigFile :: from_str (
2901
+ r#"
2902
+ [burnchain]
2903
+ chain_id = 0x00000500
2904
+ unknown_field = "test"
2905
+ chain = "bitcoin"
2906
+ "# ,
2907
+ )
2908
+ . unwrap_err ( ) ;
2909
+ assert ! ( err. starts_with( "Invalid toml: unknown field `unknown_field`" ) ) ;
2910
+ }
2911
+
2912
+ {
2913
+ let err = ConfigFile :: from_str (
2914
+ r#"
2915
+ [node]
2916
+ rpc_bind = "0.0.0.0:20443"
2917
+ unknown_field = "test"
2918
+ p2p_bind = "0.0.0.0:20444"
2919
+ "# ,
2920
+ )
2921
+ . unwrap_err ( ) ;
2922
+ assert ! ( err. starts_with( "Invalid toml: unknown field `unknown_field`" ) ) ;
2923
+ }
2924
+
2925
+ {
2926
+ let err = ConfigFile :: from_str (
2927
+ r#"
2928
+ [[ustx_balance]]
2929
+ address = "ST3AM1A56AK2C1XAFJ4115ZSV26EB49BVQ10MGCS0"
2930
+ amount = 10000000000000000
2931
+ unknown_field = "test"
2932
+ "# ,
2933
+ )
2934
+ . unwrap_err ( ) ;
2935
+ assert ! ( err. starts_with( "Invalid toml: unknown field `unknown_field`" ) ) ;
2936
+ }
2937
+
2938
+ {
2939
+ let err = ConfigFile :: from_str (
2940
+ r#"
2941
+ [[events_observer]]
2942
+ endpoint = "localhost:30000"
2943
+ unknown_field = "test"
2944
+ events_keys = ["stackerdb", "block_proposal", "burn_blocks"]
2945
+ "# ,
2946
+ )
2947
+ . unwrap_err ( ) ;
2948
+ assert ! ( err. starts_with( "Invalid toml: unknown field `unknown_field`" ) ) ;
2949
+ }
2950
+
2951
+ {
2952
+ let err = ConfigFile :: from_str (
2953
+ r#"
2954
+ [connection_options]
2955
+ inbox_maxlen = 100
2956
+ outbox_maxlen = 200
2957
+ unknown_field = "test"
2958
+ "# ,
2959
+ )
2960
+ . unwrap_err ( ) ;
2961
+ assert ! ( err. starts_with( "Invalid toml: unknown field `unknown_field`" ) ) ;
2962
+ }
2963
+
2964
+ {
2965
+ let err = ConfigFile :: from_str (
2966
+ r#"
2967
+ [fee_estimation]
2968
+ cost_estimator = "foo"
2969
+ unknown_field = "test"
2970
+ "# ,
2971
+ )
2972
+ . unwrap_err ( ) ;
2973
+ assert ! ( err. starts_with( "Invalid toml: unknown field `unknown_field`" ) ) ;
2974
+ }
2975
+
2976
+ {
2977
+ let err = ConfigFile :: from_str (
2978
+ r#"
2979
+ [miner]
2980
+ first_attempt_time_ms = 180_000
2981
+ unknown_field = "test"
2982
+ subsequent_attempt_time_ms = 360_000
2983
+ "# ,
2984
+ )
2985
+ . unwrap_err ( ) ;
2986
+ println ! ( "{}" , err) ;
2987
+ assert ! ( err. starts_with( "Invalid toml: unknown field `unknown_field`" ) ) ;
2988
+ }
2989
+
2990
+ {
2991
+ let err = ConfigFile :: from_str (
2992
+ r#"
2993
+ [atlas]
2994
+ attachments_max_size = 100
2995
+ unknown_field = "test"
2996
+ "# ,
2997
+ )
2998
+ . unwrap_err ( ) ;
2999
+ assert ! ( err. starts_with( "Invalid toml: unknown field `unknown_field`" ) ) ;
3000
+ }
3001
+ }
3002
+
2876
3003
#[ test]
2877
3004
fn should_load_legacy_mstx_balances_toml ( ) {
2878
3005
let config = ConfigFile :: from_str (
0 commit comments