11
11
from sqlalchemy .orm import sessionmaker
12
12
from sqlalchemy .ext .declarative import declarative_base
13
13
from egs_ref import *
14
+ import modelparams
14
15
15
16
web3 = Web3 (HTTPProvider ('http://localhost:8545' ))
16
17
engine = create_engine (
@@ -56,7 +57,7 @@ def write_to_sql(alltx, analyzed_block, block_sumdf, mined_blockdf_seen, block):
56
57
block_sumdf .to_sql (con = engine , name = 'blockdata2' , if_exists = 'append' , index = False )
57
58
58
59
59
- def write_to_json (gprecs , txpool_by_gp , prediction_table , analyzed_block ):
60
+ def write_to_json (gprecs , txpool_by_gp , prediction_table , analyzed_block , submitted_hourago = None ):
60
61
"""write json data"""
61
62
try :
62
63
txpool_by_gp = txpool_by_gp .rename (columns = {'gas_price' :'count' })
@@ -85,6 +86,12 @@ def write_to_json(gprecs, txpool_by_gp, prediction_table, analyzed_block):
85
86
86
87
with open (filepath_analyzedblock , 'w' ) as outfile :
87
88
outfile .write (analyzed_blockout )
89
+
90
+ if not submitted_hourago .empty :
91
+ submitted_hourago = submitted_hourago .to_json (orient = 'records' )
92
+ filepath_hourago = parentdir + '/json/hourago.json'
93
+ with open (filepath_hourago , 'w' ) as outfile :
94
+ outfile .write (submitted_hourago )
88
95
89
96
except Exception as e :
90
97
print (e )
@@ -149,13 +156,9 @@ def get_tx_atabove(gasprice, txpool_by_gp):
149
156
def predict (row ):
150
157
if row ['chained' ] == 1 :
151
158
return np .nan
152
- intercept = 3.3381
153
- hpa_coef = - 0.0172
154
- txatabove_coef = 0.001
155
- interact_coef = 0
156
- high_gas_coef = 1.6907
159
+
157
160
try :
158
- sum1 = (intercept + (row ['hashpower_accepting' ]* hpa_coef ) + (row ['tx_atabove' ]* txatabove_coef ) + (row ['hgXhpa' ]* interact_coef ) + (row ['highgas2' ]* high_gas_coef ))
161
+ sum1 = (modelparams . INTERCEPT + (row ['hashpower_accepting' ] * modelparams . HPA_COEF ) + (row ['tx_atabove' ] * modelparams . TXATABOVE_COEF ) + (row ['hgXhpa' ] * modelparams . INTERACT_COEF ) + (row ['highgas2' ] * modelparams . HIGHGAS_COEF ))
159
162
prediction = np .exp (sum1 )
160
163
if prediction < 2 :
161
164
prediction = 2
@@ -166,6 +169,14 @@ def predict(row):
166
169
print (e )
167
170
return np .nan
168
171
172
+ def check_nonce (row , txpool_block_nonce ):
173
+ if row ['num_from' ]> 1 :
174
+ if row ['nonce' ] > txpool_block_nonce .loc [row ['from_address' ],'nonce' ]:
175
+ return 1
176
+ if row ['nonce' ] == txpool_block_nonce .loc [row ['from_address' ], 'nonce' ]:
177
+ return 0
178
+ else :
179
+ return 0
169
180
170
181
def analyze_last200blocks (block , blockdata ):
171
182
recent_blocks = blockdata .loc [blockdata ['block_number' ] > (block - 200 ), ['mingasprice' , 'block_number' , 'gaslimit' , 'time_mined' , 'speed' ]]
@@ -206,10 +217,14 @@ def analyze_txpool(block, txpool, alltx, hashpower, avg_timemined, gaslimit):
206
217
txpool_block ['num_to' ] = txpool_block .groupby ('to_address' )['block_posted' ].transform ('count' )
207
218
txpool_block ['ico' ] = (txpool_block ['num_to' ] > 90 ).astype (int )
208
219
txpool_block ['dump' ] = (txpool_block ['num_from' ] > 5 ).astype (int )
209
- #group by gasprice
220
+
221
+ #new dfs grouped by gasprice and nonce
210
222
txpool_by_gp = txpool_block [['gas_price' , 'round_gp_10gwei' ]].groupby ('round_gp_10gwei' ).agg ({'gas_price' :'count' })
211
223
txpool_block_nonce = txpool_block [['from_address' , 'nonce' ]].groupby ('from_address' ).agg ({'nonce' :'min' })
212
224
225
+ #when multiple tx from same from address, finds tx with lowest nonce (unchained) - others are 'chained'
226
+ txpool_block ['chained' ] = txpool_block .apply (check_nonce , args = (txpool_block_nonce ,), axis = 1 )
227
+
213
228
#predictiontable
214
229
predictTable = pd .DataFrame ({'gasprice' : range (10 , 1010 , 10 )})
215
230
ptable2 = pd .DataFrame ({'gasprice' : range (0 , 10 , 1 )})
@@ -233,8 +248,8 @@ def analyze_txpool(block, txpool, alltx, hashpower, avg_timemined, gaslimit):
233
248
#finally, analyze txpool transactions
234
249
print ('txpool block length ' + str (len (txpool_block )))
235
250
txpool_block ['pct_limit' ] = txpool_block ['gas_offered' ].apply (lambda x : x / gaslimit )
236
- txpool_block ['high_gas_offered' ] = (txpool_block ['pct_limit' ]> .037 ).astype (int )
237
- txpool_block ['highgas2' ] = (txpool_block ['pct_limit' ] > .15 ).astype (int )
251
+ txpool_block ['high_gas_offered' ] = (txpool_block ['pct_limit' ] > modelparams . HIGHGAS1 ).astype (int )
252
+ txpool_block ['highgas2' ] = (txpool_block ['pct_limit' ] > modelparams . HIGHGAS2 ).astype (int )
238
253
txpool_block ['hashpower_accepting' ] = txpool_block ['round_gp_10gwei' ].apply (lambda x : gp_lookup [x ] if x in gp_lookup else 100 )
239
254
txpool_block ['hgXhpa' ] = txpool_block ['highgas2' ]* txpool_block ['hashpower_accepting' ]
240
255
txpool_block ['tx_atabove' ] = txpool_block ['round_gp_10gwei' ].apply (lambda x : txatabove_lookup [x ] if x in txatabove_lookup else 1 )
@@ -244,17 +259,40 @@ def analyze_txpool(block, txpool, alltx, hashpower, avg_timemined, gaslimit):
244
259
txpool_by_gp .reset_index (inplace = True , drop = False )
245
260
return (txpool_block , txpool_by_gp , predictTable )
246
261
247
- def get_gasprice_recs (prediction_table , block_time , block , speed , minlow = - 1 ):
262
+ def get_gasprice_recs (prediction_table , block_time , block , speed , minlow = - 1 , submitted_hourago = None ):
248
263
249
- def get_safelow (minlow ):
250
- series = prediction_table .loc [prediction_table ['expectedTime' ] <= 10 , 'gasprice' ]
251
- safelow = series .min ()
264
+ def get_safelow (minlow , submitted_hourago ):
265
+ series = prediction_table .loc [prediction_table ['expectedTime' ] <= 20 , 'gasprice' ]
266
+ model_safelow = series .min ()
252
267
minhash_list = prediction_table .loc [prediction_table ['hashpower_accepting' ]>= 1.5 , 'gasprice' ]
253
- if (safelow < minhash_list .min ()):
254
- safelow = minhash_list .min ()
268
+ if (model_safelow < minhash_list .min ()):
269
+ model_safelow = minhash_list .min ()
255
270
if minlow >= 0 :
256
- if safelow < minlow :
257
- safelow = minlow
271
+ if model_safelow < minlow :
272
+ model_safelow = minlow
273
+ print ('modelled safelow ' + str (model_safelow ))
274
+ if not submitted_hourago .empty :
275
+ series = submitted_hourago .loc [(submitted_hourago ['total' ]>= 5 ) & (submitted_hourago ['pct_unmined' ]>= .1 ) & (submitted_hourago ['still_here' ]>= 2 )]
276
+ if not series .empty :
277
+ unsafe = series .index .max ()
278
+ else :
279
+ unsafe = 0
280
+ print ('unsafe = ' + str (unsafe ))
281
+ series1 = submitted_hourago .loc [(submitted_hourago ['total' ]>= 3 ) & ((submitted_hourago ['pct_unmined' ]< .1 ) | (submitted_hourago ['still_here' ] <= 1 ))]
282
+ observed_safelow = series1 .loc [series1 .index > unsafe ]
283
+ if not observed_safelow .empty :
284
+ observed_safelow = observed_safelow .index .min ()
285
+ else :
286
+ observed_safelow = unsafe + 10
287
+ print ('observed safelow = ' + str (observed_safelow ))
288
+ else :
289
+ observed_safelow = 0
290
+
291
+ if unsafe > model_safelow :
292
+ safelow = observed_safelow
293
+ else :
294
+ safelow = model_safelow
295
+ print ('safelow ' + str (safelow ))
258
296
return float (safelow )
259
297
260
298
def get_average ():
@@ -293,7 +331,7 @@ def get_wait(gasprice):
293
331
return float (wait )
294
332
295
333
gprecs = {}
296
- gprecs ['safeLow' ] = get_safelow (minlow )
334
+ gprecs ['safeLow' ] = get_safelow (minlow , submitted_hourago )
297
335
gprecs ['safeLowWait' ] = get_wait (gprecs ['safeLow' ])
298
336
gprecs ['average' ] = get_average ()
299
337
gprecs ['avgWait' ] = get_wait (gprecs ['average' ])
@@ -367,16 +405,28 @@ def update_dataframes(block):
367
405
assert analyzed_block .index .duplicated ().sum ()== 0
368
406
alltx = alltx .combine_first (analyzed_block )
369
407
408
+ submitted_hourago = alltx .loc [(alltx ['block_posted' ] < (block - 250 )) & (alltx ['block_posted' ] > (block - 350 )) & (alltx ['chained' ]== 0 ) & (alltx ['gas_offered' ] < 500000 )].copy ()
409
+ print (len (submitted_hourago ))
410
+
411
+ if len (submitted_hourago > 50 ):
412
+ submitted_hourago ['still_here' ] = submitted_hourago .index .isin (current_txpool .index )
413
+ submitted_hourago = submitted_hourago [['gas_price' , 'round_gp_10gwei' , 'still_here' ]].groupby ('round_gp_10gwei' ).agg ({'gas_price' :'count' , 'still_here' :'sum' })
414
+ submitted_hourago .rename (columns = {'gas_price' :'total' }, inplace = True )
415
+ submitted_hourago ['pct_unmined' ] = submitted_hourago ['still_here' ]/ submitted_hourago ['total' ]
416
+
370
417
#with pd.option_context('display.max_columns', None,):
371
418
#print(analyzed_block)
372
419
# update tx dataframe with txpool variables and time preidctions
373
420
374
421
#get gpRecs
375
- gprecs = get_gasprice_recs (predictiondf , block_time , block , speed , timer .minlow )
422
+ gprecs = get_gasprice_recs (predictiondf , block_time , block , speed , timer .minlow , submitted_hourago )
376
423
377
424
#every block, write gprecs, predictions, txpool by gasprice
378
425
analyzed_block .reset_index (drop = False , inplace = True )
379
- write_to_json (gprecs , txpool_by_gp , predictiondf , analyzed_block )
426
+ if not submitted_hourago .empty :
427
+ submitted_hourago .reset_index (drop = False , inplace = True )
428
+ submitted_hourago = submitted_hourago .sort_values ('round_gp_10gwei' )
429
+ write_to_json (gprecs , txpool_by_gp , predictiondf , analyzed_block , submitted_hourago )
380
430
write_to_sql (alltx , analyzed_block , block_sumdf , mined_blockdf_seen , block )
381
431
382
432
#keep from getting too large
0 commit comments