@@ -37,90 +37,141 @@ func NewParamsFromValues(assignments map[string]interface{}) (*types.RunParams,
3737 params := * DefaultParams
3838
3939 for k , v := range assignments {
40- switch k {
41- case "payload" :
42- if vPtrStr , ok := v .(* string ); ok {
43- params .PayloadID = string (* vPtrStr )
44- } else if vStr , ok := v .(string ); ok {
45- params .PayloadID = string (vStr )
46- } else {
47- return nil , fmt .Errorf ("invalid payload %s" , v )
48- }
49- case "node_type" :
50- if vStr , ok := v .(string ); ok {
51- params .NodeType = vStr
52- } else {
53- return nil , fmt .Errorf ("invalid node type %s" , v )
54- }
55- case "client_bin" :
56- if vStr , ok := v .(string ); ok {
57- params .ClientBinPath = vStr
58- } else {
59- return nil , fmt .Errorf ("invalid client bin %s" , v )
60- }
61- case "validator_node_type" :
62- if vStr , ok := v .(string ); ok {
63- params .ValidatorNodeType = vStr
64- } else {
65- return nil , fmt .Errorf ("invalid validator node type %s" , v )
66- }
67- case "gas_limit" :
68- if vInt , ok := v .(int ); ok {
69- params .GasLimit = uint64 (vInt )
70- } else {
71- return nil , fmt .Errorf ("invalid gas limit %s" , v )
72- }
73- case "consensus_timing" :
74- if vStr , ok := v .(string ); ok {
75- if vStr != "" && vStr != types .ConsensusTimingModePreventLateFCU && vStr != types .ConsensusTimingModeBaseConsensus {
76- return nil , fmt .Errorf ("invalid consensus timing %s" , v )
77- }
78- params .ConsensusTimingMode = vStr
79- } else {
80- return nil , fmt .Errorf ("invalid consensus timing %s" , v )
40+ if err := applyParam (& params , k , v ); err != nil {
41+ return nil , err
42+ }
43+ }
44+
45+ return & params , nil
46+ }
47+
48+ func applyParam (params * types.RunParams , k string , v interface {}) error {
49+ if k == "params" {
50+ return applyParamGroup (params , v )
51+ }
52+
53+ switch k {
54+ case "payload" :
55+ if vPtrStr , ok := v .(* string ); ok {
56+ params .PayloadID = string (* vPtrStr )
57+ } else if vStr , ok := v .(string ); ok {
58+ params .PayloadID = string (vStr )
59+ } else {
60+ return fmt .Errorf ("invalid payload %s" , v )
61+ }
62+ case "node_type" :
63+ if vStr , ok := v .(string ); ok {
64+ params .NodeType = vStr
65+ } else {
66+ return fmt .Errorf ("invalid node type %s" , v )
67+ }
68+ case "client_bin" :
69+ if vStr , ok := v .(string ); ok {
70+ params .ClientBinPath = vStr
71+ } else {
72+ return fmt .Errorf ("invalid client bin %s" , v )
73+ }
74+ case "validator_node_type" :
75+ if vStr , ok := v .(string ); ok {
76+ params .ValidatorNodeType = vStr
77+ } else {
78+ return fmt .Errorf ("invalid validator node type %s" , v )
79+ }
80+ case "gas_limit" :
81+ if vInt , ok := v .(int ); ok {
82+ params .GasLimit = uint64 (vInt )
83+ } else {
84+ return fmt .Errorf ("invalid gas limit %s" , v )
85+ }
86+ case "load_test_config" :
87+ overrides , err := normalizeStringKeyMap (v )
88+ if err != nil {
89+ return fmt .Errorf ("invalid load test config %v" , v )
90+ }
91+ params .LoadTestConfigOverrides = overrides
92+ case "consensus_timing" :
93+ if vStr , ok := v .(string ); ok {
94+ if vStr != "" && vStr != types .ConsensusTimingModePreventLateFCU && vStr != types .ConsensusTimingModeBaseConsensus {
95+ return fmt .Errorf ("invalid consensus timing %s" , v )
8196 }
82- case "env" :
83- if vStr , ok := v .(string ); ok {
84- entries := strings .Split (vStr , ";" )
85- params .Env = make (map [string ]string )
86- for _ , entry := range entries {
87- kv := strings .Split (entry , "=" )
88- if len (kv ) != 2 {
89- return nil , fmt .Errorf ("invalid env entry %s" , entry )
90- }
91- params .Env [kv [0 ]] = kv [1 ]
97+ params .ConsensusTimingMode = vStr
98+ } else {
99+ return fmt .Errorf ("invalid consensus timing %s" , v )
100+ }
101+ case "env" :
102+ if vStr , ok := v .(string ); ok {
103+ entries := strings .Split (vStr , ";" )
104+ params .Env = make (map [string ]string )
105+ for _ , entry := range entries {
106+ kv := strings .Split (entry , "=" )
107+ if len (kv ) != 2 {
108+ return fmt .Errorf ("invalid env entry %s" , entry )
92109 }
93- } else {
94- return nil , fmt .Errorf ("invalid env %s" , v )
110+ params .Env [kv [0 ]] = kv [1 ]
95111 }
96- case "num_blocks" :
97- if vInt , ok := v .(int ); ok {
98- params .NumBlocks = vInt
99- } else {
100- return nil , fmt .Errorf ("invalid num blocks %s" , v )
101- }
102- case "node_args" :
103- // either a list of strings or a string (separated by spaces)
104- if vStr , ok := v .(string ); ok {
105- params .NodeArgs = strings .Split (vStr , " " )
106- } else if vArr , ok := v .([]interface {}); ok {
107- // convert []interface{} to []string
108- nodeArgs := make ([]string , len (vArr ))
109- for i , arg := range vArr {
110- arg , ok := arg .(string )
111- if ! ok {
112- return nil , fmt .Errorf ("invalid non-string node arg %v" , arg )
113- }
114- nodeArgs [i ] = arg
112+ } else {
113+ return fmt .Errorf ("invalid env %s" , v )
114+ }
115+ case "num_blocks" :
116+ if vInt , ok := v .(int ); ok {
117+ params .NumBlocks = vInt
118+ } else {
119+ return fmt .Errorf ("invalid num blocks %s" , v )
120+ }
121+ case "node_args" :
122+ // either a list of strings or a string (separated by spaces)
123+ if vStr , ok := v .(string ); ok {
124+ params .NodeArgs = strings .Split (vStr , " " )
125+ } else if vArr , ok := v .([]interface {}); ok {
126+ // convert []interface{} to []string
127+ nodeArgs := make ([]string , len (vArr ))
128+ for i , arg := range vArr {
129+ arg , ok := arg .(string )
130+ if ! ok {
131+ return fmt .Errorf ("invalid non-string node arg %v" , arg )
115132 }
116- params .NodeArgs = nodeArgs
117- } else {
118- return nil , fmt .Errorf ("invalid node args %v" , v )
133+ nodeArgs [i ] = arg
119134 }
135+ params .NodeArgs = nodeArgs
136+ } else {
137+ return fmt .Errorf ("invalid node args %v" , v )
120138 }
121139 }
140+ return nil
141+ }
122142
123- return & params , nil
143+ func applyParamGroup (params * types.RunParams , value interface {}) error {
144+ // A params value groups multiple assignments into one matrix dimension,
145+ // preserving relationships between values that should vary together.
146+ expanded , err := normalizeStringKeyMap (value )
147+ if err != nil {
148+ return fmt .Errorf ("invalid params %v" , value )
149+ }
150+ for param , value := range expanded {
151+ if err := applyParam (params , param , value ); err != nil {
152+ return fmt .Errorf ("invalid params.%s: %w" , param , err )
153+ }
154+ }
155+ return nil
156+ }
157+
158+ func normalizeStringKeyMap (value interface {}) (map [string ]interface {}, error ) {
159+ switch typed := value .(type ) {
160+ case map [string ]interface {}:
161+ return typed , nil
162+ case map [interface {}]interface {}:
163+ out := make (map [string ]interface {}, len (typed ))
164+ for key , value := range typed {
165+ keyString , ok := key .(string )
166+ if ! ok {
167+ return nil , fmt .Errorf ("non-string key %v" , key )
168+ }
169+ out [keyString ] = value
170+ }
171+ return out , nil
172+ default :
173+ return nil , fmt .Errorf ("expected mapping" )
174+ }
124175}
125176
126177const MAX_GAS_LIMIT = math .MaxUint64
0 commit comments