@@ -44,7 +44,8 @@ namespace cbdc::parsec::agent::runner {
44
44
PyObject* localDictionary = PyDict_New ();
45
45
46
46
if (m_function.size () == 0 ) {
47
- m_log->error (" Contract has length 0, key may be invalid" );
47
+ m_log->warn (
48
+ " Contract has length 0, key may be invalid. Bailing out." );
48
49
m_result_callback (runtime_locking_shard::state_update_type ());
49
50
return true ;
50
51
}
@@ -54,7 +55,7 @@ namespace cbdc::parsec::agent::runner {
54
55
// Parse the parameters buffer into its component strings.
55
56
auto params = parse_params ();
56
57
57
- for (runtime_locking_shard::key_type key : m_shard_inputs) {
58
+ for (runtime_locking_shard::key_type& key : m_shard_inputs) {
58
59
auto dest = cbdc::buffer ();
59
60
auto valid_resp = std::promise<bool >();
60
61
@@ -70,6 +71,7 @@ namespace cbdc::parsec::agent::runner {
70
71
auto data = handle_try_lock_input_arg (std::move (res), dest);
71
72
valid_resp.set_value (data);
72
73
});
74
+
73
75
if (!success) {
74
76
m_log->error (" Failed to issue try lock command" );
75
77
m_result_callback (error_code::internal_error);
@@ -82,7 +84,7 @@ namespace cbdc::parsec::agent::runner {
82
84
" to be \" 0\" " );
83
85
dest.append (" 0" , 2 );
84
86
}
85
- params.push_back (dest.c_str ());
87
+ params.emplace_back (dest.c_str ());
86
88
}
87
89
88
90
if (m_input_args.size () != params.size ()) {
@@ -97,11 +99,11 @@ namespace cbdc::parsec::agent::runner {
97
99
value);
98
100
}
99
101
100
- auto r = PyRun_String (m_function.c_str (),
101
- Py_file_input,
102
- globalDictionary,
103
- localDictionary);
104
- if (!r ) {
102
+ auto * r = PyRun_String (m_function.c_str (),
103
+ Py_file_input,
104
+ globalDictionary,
105
+ localDictionary);
106
+ if (r == nullptr ) {
105
107
m_log->error (" Python VM generated error:" , r);
106
108
}
107
109
update_state (localDictionary);
@@ -116,7 +118,8 @@ namespace cbdc::parsec::agent::runner {
116
118
void py_runner::parse_header () {
117
119
/* Assumes that header is <n returns> <n inputs> | return types |
118
120
return args | input types | input args | function code */
119
- auto functionString = std::string ((char *)m_function.data ());
121
+ auto functionString
122
+ = std::string (static_cast <char *>(m_function.data ()));
120
123
121
124
m_input_args.clear ();
122
125
m_return_args.clear ();
@@ -130,17 +133,15 @@ namespace cbdc::parsec::agent::runner {
130
133
131
134
arg_delim = functionString.find (' |' );
132
135
arg_string = functionString.substr (0 , arg_delim);
133
- pos = 0 ;
134
- while ((pos = arg_string.find (" ," , 0 )) != std::string::npos) {
136
+ while ((pos = arg_string.find (' ,' , 0 )) != std::string::npos) {
135
137
m_return_args.push_back (arg_string.substr (0 , pos));
136
138
arg_string.erase (0 , pos + 1 );
137
139
}
138
140
functionString.erase (0 , arg_delim + 1 );
139
141
140
142
arg_delim = functionString.find (' |' );
141
143
arg_string = functionString.substr (0 , arg_delim);
142
- pos = 0 ;
143
- while ((pos = arg_string.find (" ," , 0 )) != std::string::npos) {
144
+ while ((pos = arg_string.find (' ,' , 0 )) != std::string::npos) {
144
145
m_input_args.push_back (arg_string.substr (0 , pos));
145
146
arg_string.erase (0 , pos + 1 );
146
147
}
@@ -159,57 +160,76 @@ namespace cbdc::parsec::agent::runner {
159
160
m_log->error (" m_param contains no data" );
160
161
return params;
161
162
}
163
+ m_param.append (" \0 " , 1 );
162
164
size_t pipeCount = 0 ;
163
165
size_t stringCount = 0 ;
166
+ auto paramString
167
+ = std::string (static_cast <char *>(m_param.data ()), m_param.size ());
164
168
for (size_t i = 0 ; i < m_param.size (); i++) {
165
- if ((( char *)m_param. data ()) [i] == ' |' ) {
169
+ if (paramString [i] == ' |' ) {
166
170
pipeCount++;
167
- } else if (i > 0 && ( int )(( char *)m_param. data ()) [i] == 0
168
- && ( int )(( char *)m_param. data ()) [i - 1 ] != 0 ) {
171
+ } else if (i > 0 && paramString [i] == ' \0 '
172
+ && paramString [i - 1 ] != ' \0 ' ) {
169
173
stringCount++;
170
174
}
171
175
}
176
+ auto bail = false ;
172
177
if (pipeCount != 3 ) {
173
178
m_log->error (" m_param sections are improperly formatted" );
174
- return params ;
179
+ bail = true ;
175
180
} else if (stringCount
176
181
!= m_input_args.size () + m_return_args.size () + pipeCount) {
177
182
m_log->error (" m_param contains too few arguments or arguments are "
178
183
" improperly formatted" );
184
+ bail = true ;
185
+ }
186
+ if (bail) {
179
187
return params;
180
188
}
181
- m_param.append (" \0 " , 1 );
182
189
// ---
183
190
184
- char * paramString = (char *)m_param.data ();
185
-
186
191
// get parameters that are user inputs
187
- while (*paramString != ' |' ) {
188
- params.emplace_back (paramString);
189
- paramString += params.back ().length () + 1 ;
190
- }
191
- paramString += 2 ;
192
-
193
- // get parameters which are to be pulled from shards
194
- while (*paramString != ' |' ) {
195
- auto tmp = cbdc::buffer ();
196
- // / \todo Prefer a solution which does not use strlen
197
- tmp.append (paramString, std::strlen (paramString) + 1 );
198
-
199
- m_shard_inputs.emplace_back (tmp);
200
- // / \todo Prefer a solution which does not use strlen
201
- paramString += std::strlen (paramString) + 1 ;
202
- }
203
- paramString += 2 ;
204
-
205
- // get the state update keys
206
- while (*paramString != ' |' ) { // was previously '\0'
207
- auto tmp = cbdc::buffer ();
208
- tmp.append (paramString, std::strlen (paramString) + 1 );
209
-
210
- m_update_keys.emplace_back (tmp);
211
- // / \todo Prefer a solution which does not use strlen
212
- paramString += std::strlen (paramString) + 1 ;
192
+ size_t bufferOffset = 0 ;
193
+ auto it = 0 ;
194
+ // Known that there are 3 parts of the header
195
+ while (it < 3 ) {
196
+ auto parsedParam = std::string (
197
+ static_cast <char *>(m_param.data_at (bufferOffset)));
198
+ if (parsedParam[0 ] == ' |' ) {
199
+ it++;
200
+ bufferOffset += 2 ;
201
+ continue ;
202
+ }
203
+ switch (it) {
204
+ /*
205
+ In first section, take data and place in params
206
+ In second section, take data and place in m_shard_inputs
207
+ In third section, take data and place in m_update_keys
208
+ */
209
+ case 0 :
210
+ params.emplace_back (std::string (parsedParam));
211
+ bufferOffset += params.back ().length () + 1 ;
212
+ break ;
213
+ case 1 : {
214
+ auto tmp = cbdc::buffer ();
215
+ tmp.append (parsedParam.c_str (), parsedParam.length () + 1 );
216
+ m_shard_inputs.emplace_back (tmp);
217
+ bufferOffset += tmp.size ();
218
+ break ;
219
+ }
220
+ case 2 : {
221
+ auto tmp = cbdc::buffer ();
222
+ tmp.append (parsedParam.c_str (), parsedParam.length () + 1 );
223
+ m_update_keys.emplace_back (tmp);
224
+ bufferOffset += tmp.size ();
225
+ break ;
226
+ }
227
+ default :
228
+ m_log->fatal (
229
+ " Reading past the number of input group "
230
+ " sections. Something has gone seriously wrong." );
231
+ continue ;
232
+ }
213
233
}
214
234
215
235
return params;
@@ -251,8 +271,6 @@ namespace cbdc::parsec::agent::runner {
251
271
252
272
// Communicate updates to agent scope. Will write back to shards.
253
273
m_result_callback (std::move (updates));
254
-
255
- return ;
256
274
}
257
275
258
276
void py_runner::handle_try_lock (
@@ -285,9 +303,7 @@ namespace cbdc::parsec::agent::runner {
285
303
res);
286
304
if (maybe_error.has_value ()) {
287
305
m_result_callback (maybe_error.value ());
288
- return ;
289
306
}
290
- return ;
291
307
}
292
308
293
309
auto py_runner::handle_try_lock_input_arg (
@@ -331,8 +347,8 @@ namespace cbdc::parsec::agent::runner {
331
347
for (size_t i = 0 ; i < m_return_types.size (); i++) {
332
348
auto ch = m_return_types[i];
333
349
m_log->trace (" Parsing:" , m_return_args[i].c_str ());
334
- auto word = PyDict_GetItemString (localDictionary,
335
- m_return_args[i].c_str ());
350
+ auto * word = PyDict_GetItemString (localDictionary,
351
+ m_return_args[i].c_str ());
336
352
auto buf = cbdc::buffer ();
337
353
switch (ch) {
338
354
case ' l' : {
@@ -349,16 +365,16 @@ namespace cbdc::parsec::agent::runner {
349
365
}
350
366
case ' s' : {
351
367
m_log->trace (" Parsing string" );
352
- char * res;
368
+ char * res = nullptr ;
353
369
if (PyUnicode_Check (word)) {
354
- res = PyBytes_AS_STRING (
370
+ res = PyBytes_AsString (
355
371
PyUnicode_AsEncodedString (word,
356
372
" UTF-8" ,
357
373
" strict" ));
358
374
} else {
359
375
res = PyBytes_AsString (word);
360
376
}
361
- if (res) {
377
+ if (res != nullptr ) {
362
378
// PyBytes_AsString returns a null terminated string
363
379
buf.append (res, strlen (res) + 1 );
364
380
}
@@ -373,16 +389,16 @@ namespace cbdc::parsec::agent::runner {
373
389
}
374
390
case ' c' : {
375
391
m_log->trace (" Parsing char" );
376
- char * res;
392
+ char * res = nullptr ;
377
393
if (PyUnicode_Check (word)) {
378
- res = PyBytes_AS_STRING (
394
+ res = PyBytes_AsString (
379
395
PyUnicode_AsEncodedString (word,
380
396
" UTF-8" ,
381
397
" strict" ));
382
398
} else {
383
399
res = PyBytes_AsString (word);
384
400
}
385
- if (res) {
401
+ if (res != nullptr ) {
386
402
buf.append (res, strnlen (res, 1 ));
387
403
}
388
404
break ;
@@ -393,6 +409,5 @@ namespace cbdc::parsec::agent::runner {
393
409
}
394
410
m_return_values.push_back (buf);
395
411
}
396
- return ;
397
412
}
398
413
}
0 commit comments