-
Notifications
You must be signed in to change notification settings - Fork 48
/
sql.py
2543 lines (2150 loc) · 122 KB
/
sql.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
import datetime
import decimal
import math
import sys
import requests
from rpcclient import *
from omniutils import *
from sqltools import *
from common import *
def reparsetx_MP(txhash):
printdebug(("Reparsing TX",txhash),4)
Protocol="Omni"
try:
rawtx=gettransaction_MP(txhash)
except Exception:
printdebug(("Not a MP tx",txhash),4)
exit(1)
tx=dbSelect("select txblocknumber, txseqinblock, txdbserialnum, txstate, txtype from transactions where txhash=%s",[txhash])
if len(tx)==1:
tx=tx[0]
else:
printdebug(("Error, duplicate tx's found for",txhash),4)
exit(1)
blockheight = tx[0]
seq = tx[1]
TxDBSerialNum = tx[2]
txstate = tx[3]
txtype = tx[4]
if txtype not in [0,3,4,25,-1,200]:
printdebug(("Can't Reparse txtype",txtype,"in middle of data, try running reorg rollback code"),4)
exit(1)
if txstate=='valid':
addressesintxs=dbSelect("select address, addressrole, protocol, propertyid, balanceavailablecreditdebit, balancereservedcreditdebit, balanceacceptedcreditdebit, balancefrozencreditdebit, linkedtxdbserialnum "
"from addressesintxs where txdbserialnum=%s", [TxDBSerialNum])
for entry in addressesintxs:
Address=entry[0]
Role=entry[1]
Protocol=entry[2]
PropertyID=entry[3]
Ecosystem=getEcosystem(PropertyID)
linkedtxdbserialnum=entry[8]
#figure out how much 'moved' and undo it in addressbalances
if entry[4] == None:
dbBalanceAvailable = 0
else:
dbBalanceAvailable = entry[4]*-1
if entry[5] == None:
dbBalanceReserved = 0
else:
dbBalanceReserved = entry[5]*-1
if entry[6] == None:
dbBalanceAccepted = 0
else:
dbBalanceAccepted = entry[6]*-1
if entry[7] == None:
dbBalanceFrozen = 0
else:
dbBalanceFrozen = entry[7]*-1
#use -1 for txdbserialnum as we don't know what the previous tx that last modified it's balanace was.
updateBalance(Address, Protocol, PropertyID, Ecosystem, dbBalanceAvailable, dbBalanceReserved, dbBalanceAccepted, -TxDBSerialNum, dbBalanceFrozen)
#/end for entry in addressesintxs
#/end if txstate='valid'
#purge the transaction from the tables
dbExecute("delete from txjson where txdbserialnum=%s",[TxDBSerialNum])
dbExecute("delete from addressesintxs where txdbserialnum=%s",[TxDBSerialNum])
dbExecute("delete from transactions where txdbserialnum=%s",[TxDBSerialNum])
#reparse/insert the tx/addressesintx
insertTx(rawtx, Protocol, blockheight, seq, TxDBSerialNum)
insertTxAddr(rawtx, Protocol, TxDBSerialNum, blockheight)
def reorgRollback(block):
printdebug(("Reorg Detected, Rolling back to block ",block),4)
BlockTime=dbSelect("select extract(epoch from blocktime) from blocks where blocknumber=%s",[block])[0][0]
#list of tx's we have processed since the reorg
txs=dbSelect("select txdbserialnum,txtype,txstate,txblocknumber from transactions where txblocknumber >%s order by txdbserialnum desc",[block])
#(need to reset txdbserialnum counter when done)
txcount=len(txs)
#================================================================
#--------------Remove this block when BTC tx's go in-------------
#don't have btc tx's yet in db add extra step to get count of those
txcount+=dbSelect("select sum(txcount) from blocks where blocknumber >%s",[block])[0][0]
#================================================================
newTxDBSerialNum=dbSelect('select last_value from transactions_txdbserialnum_seq',None)[0][0]-txcount
printdebug(("Removing",txcount,"transactions and setting txdbserialnum to",newTxDBSerialNum),4)
#last block in the db parsed, we'll work backwards from there to block
#lastBlock=dbSelect("select max(blocknumber) from blocks", None)[0][0]
#walk backwards undoing each tx we have a record for
for tx in txs:
TxDbSerialNum=tx[0]
txtype=tx[1]
txstate=tx[2]
txblocknumber=tx[3]
#undo any expired accepts before we walk back the tx in that block, we'll need to call again once done just in case we didn't have any tx for the first block
expireAccepts(-txblocknumber)
#only undo balance/state changes a valid tx created
if txstate=='valid':
addressesintxs=dbSelect("select address, addressrole, protocol, propertyid, balanceavailablecreditdebit, balancereservedcreditdebit, balanceacceptedcreditdebit,linkedtxdbserialnum "
"from addressesintxs where txdbserialnum=%s", [TxDbSerialNum])
for entry in addressesintxs:
Address=entry[0]
Role=entry[1]
Protocol=entry[2]
PropertyID=entry[3]
Ecosystem=getEcosystem(PropertyID)
linkedtxdbserialnum=entry[7]
#figure out how much 'moved' and undo it in addressbalances
if entry[4] == None:
dbBalanceAvailable = 0
else:
dbBalanceAvailable = entry[4]*-1
if entry[5] == None:
dbBalanceReserved = 0
else:
dbBalanceReserved = entry[5]*-1
if entry[6] == None:
dbBalanceAccepted = 0
else:
dbBalanceAccepted = entry[6]*-1
#use -1 for txdbserialnum as we don't know what the previous tx that last modified it's balanace was.
updateBalance(Address, Protocol, PropertyID, Ecosystem, dbBalanceAvailable, dbBalanceReserved, dbBalanceAccepted, -TxDbSerialNum)
if Protocol=="Omni":
#any special actions need to be undone as well
if txtype == 20 and Role=='seller':
try:
rawtx=json.loads(dbSelect("select txdata from txjson where txdbserialnum=%s",[TxDbSerialNum])[0][0])
except TypeError:
rawtx=dbSelect("select txdata from txjson where txdbserialnum=%s",[TxDbSerialNum])[0][0]
if 'subaction' in rawtx and rawtx['subaction'].lower()=='cancel':
printdebug(("Uncancelling DEx.1 sale",linkedtxdbserialnum,"from transaction",TxDbSerialNum,Address),7)
#cancellation, undo the cancellation (not sure about the lasttxdbserialnum yet
dbExecute("update activeoffers set offerstate='active',lasttxdbserialnum=-1 where createtxdbserialnum=%s", [linkedtxdbserialnum])
elif 'action' in rawtx and rawtx['action'].lower()=='cancel':
printdebug(("Uncancelling DEx.1 sale",linkedtxdbserialnum,"from transaction",TxDbSerialNum,Address),7)
#cancellation, undo the cancellation (not sure about the lasttxdbserialnum yet
dbExecute("update activeoffers set offerstate='active',lasttxdbserialnum=-1 where createtxdbserialnum=%s", [linkedtxdbserialnum])
else:
printdebug(("Deleting new DEx.1 sale",TxDbSerialNum,Address),7)
#was a new sale, delete it
dbExecute("delete from activeoffers where createtxdbserialnum=%s", [TxDbSerialNum])
elif txtype == 22 and Role=='seller':
#unaccept a dex sale and update the sale balance info (don't know about lasttxdbserialnum yet)
saletxdbserialnum=dbSelect("select saletxdbserialnum from offeraccepts where linkedtxdbserialnum=%s", [TxDbSerialNum])[0][0]
dbExecute("update activeoffers set amountaccepted=amountaccepted+%s::numeric, amountavailable=amountavailable-%s::numeric, "
"lasttxdbserialnum=-1 where createtxdbserialnum=%s",(dbBalanceAccepted,dbBalanceAccepted,saletxdbserialnum))
#remove the entry from the offeraccepts table
dbExecute("delete from offeraccepts where linkedtxdbserialnum=%s", [TxDbSerialNum])
elif txtype == -22:
#we have inverse of the balance numbers coming from the db variables so do the 'opposite' of what we would expect
if Role=='seller':
dbExecute("update activeoffers set offerstate='active', amountaccepted=amountaccepted+%s::numeric where createtxdbserialnum=%s",
(dbBalanceReserved,linkedtxdbserialnum))
elif Role=='buyer':
dbExecute("update offeraccepts set dexstate='unpaid', amountaccepted=amountaccepted-%s::numeric, amountpurchased=amountpurchased+%s::numeric "
"where linkedtxdbserialnum=%s",(dbBalanceAvailable,dbBalanceAvailable,linkedtxdbserialnum))
elif txtype == 50 or txtype == 51 or txtype == 54:
#remove the property and the property history information
dbExecute("delete from smartproperties where createtxdbserialnum=%s and propertyid=%s and protocol=%s",
(TxDbSerialNum,PropertyID,Protocol))
dbExecute("delete from propertyhistory where txdbserialnum=%s and propertyid=%s and protocol=%s",
(TxDbSerialNum,PropertyID,Protocol))
elif txtype == -51 or txtype == 53 or txtype == 55 or txtype == 56:
#remove entries from the property history table only
dbExecute("delete from propertyhistory where txdbserialnum=%s and propertyid=%s and protocol=%s",
(TxDbSerialNum,PropertyID,Protocol))
elif txtype == 70 and Role == "issuer":
updateProperty(PropertyID, Protocol, linkedtxdbserialnum)
#/end for entry in addressesintxs
#/end if txstate='valid'
#purge the transaction from the tables
dbExecute("delete from txjson where txdbserialnum=%s",[TxDbSerialNum])
dbExecute("delete from addressesintxs where txdbserialnum=%s",[TxDbSerialNum])
dbExecute("delete from transactions where txdbserialnum=%s",[TxDbSerialNum])
#/end for tx in txs:
#Make sure we process any remaining expires that need to be undone if we didn't have an msc tx in the block
expireAccepts(-(block+1))
expireCrowdsales(-BlockTime, "Omni")
#delete from txstats once we rollback all other data
dbExecute("delete from txstats where blocknumber>%s",[block])
#delete from blocks once we rollback all other data
dbExecute("delete from blocks where blocknumber>%s",[block])
#reset txdbserialnum field to what it was before these blocks/tx went in
dbExecute("select setval('transactions_txdbserialnum_seq', %s)",[newTxDBSerialNum])
def updateConsensusHash():
data=omni_getcurrentconsensushash()
if 'result' in data:
data=data['result']
block = data['block']
bhash = data['blockhash']
chash = data['consensushash']
dbExecute("update blocks set consensushash=%s where blocknumber=%s and blockhash=%s",
(chash,block,bhash))
def updateLastRun():
dbExecute("with upsert as "
"(update settings set updated_at=DEFAULT where key='parserLastRun' returning *) "
"insert into settings (key,value) select 'parserLastRun','see updated_at timestamp' "
"where not exists (select * from upsert)")
def updateTxStats():
ROWS=dbSelect("select blocknumber,blocktime from blocks order by blocknumber desc limit 1")
curblock=ROWS[0][0]
btime=ROWS[0][1]
ROWS=dbSelect("select coalesce(max(blocknumber),252316) from txstats")
lastblock=ROWS[0][0]
nextblock=lastblock+1
printdebug(("TxStats: lastblock",lastblock,", curblock:",str(curblock)),0)
count=0
while (nextblock <= curblock and count <= 25000):
if updateTxStatsBlock(nextblock):
printdebug(("TxStats: Block",nextblock,"processed"),0)
else:
printdebug(("TxStats: Block",nextblock,"FAILED"),0)
nextblock+=1
count+=1
dbCommit()
def updateTxStatsBlock(blocknumber):
try:
_block=int(blocknumber)
except:
return False
try:
ROWS=dbSelect("select blocknumber,blocktime from blocks where blocknumber=%s order by blocknumber desc limit 1",[_block])
curblock=ROWS[0][0]
btime=ROWS[0][1]
TROWS=dbSelect("select count(*) from transactions where txrecvtime >= %s - '1 day'::INTERVAL and txrecvtime <= %s and txdbserialnum>0",(btime,btime))
txs=TROWS[0][0]
BROWS=dbSelect("select count(*) from transactions where txblocknumber=%s",[curblock])
btxs=BROWS[0][0]
txfsum=dbSelect("select atx.propertyid, sum(abs(atx.balanceavailablecreditdebit)) FILTER (WHERE tx.txstate = 'valid'), sp.propertydata->>'divisible' as divisible, "
"count(atx.propertyid) FILTER (WHERE tx.txstate = 'valid') as count, count(atx.propertyid) FILTER (WHERE tx.txstate = 'not valid') AS invalid "
"from addressesintxs atx, transactions tx, smartproperties sp "
"where atx.txdbserialnum=tx.txdbserialnum and atx.propertyid=sp.propertyid and sp.protocol='Omni' and "
"tx.txblocknumber=%s and (atx.addressrole!='buyer' and atx.addressrole!='recipient') group by atx.propertyid, sp.propertydata->>'divisible'",[curblock])
try:
VROWS=dbSelect("select sum(cast(value->>'total_usd' as numeric)) from txstats where blocktime >= %s - '1 day'::INTERVAL and blocktime <= %s",(btime,btime))
tval_day=int(VROWS[0][0])
except:
tval_day=0
valuelist={}
total=0
rbtcusd=dbSelect("select rate1for2 from exchangerates where protocol1='Fiat' and protocol2='Bitcoin' and propertyid1=0 and propertyid2=0 order by asof desc limit 1")
try:
btcusd=decimal.Decimal(rbtcusd[0][0])
except:
btcusd=decimal.Decimal(0)
for t in txfsum:
pid=t[0]
volume=decimal.Decimal(t[1])
divisible=t[2]
count=t[3]
invalid=t[4]
if divisible in ['true','True',True]:
volume=decimal.Decimal(volume)/decimal.Decimal(1e8)
rawrate=dbSelect("select rate1for2 from exchangerates where protocol1='Bitcoin' and protocol2='Omni' and propertyid1=0 and propertyid2=%s order by asof desc limit 1",[pid])
try:
rate=decimal.Decimal(rawrate[0][0])
except:
rate=decimal.Decimal(0)
value=rate*btcusd*volume
rateusd=rate*btcusd
srate=str(float(rateusd)).split('.')
prate=decimal.Decimal(srate[0]+'.'+srate[1][:8])
value=int(round(value))
total+=value
valuelist[pid]={'rate_usd':str(prate),'volume':str(volume),'value_usd_rounded':value, 'tx_count': count , 'invalid': invalid}
fvalue={'total_usd':total, 'details':valuelist, 'value_24hr':tval_day}
dbExecute("insert into txstats (blocknumber,blocktime,txcount,blockcount,value) values(%s,%s,%s,%s,%s)",
(curblock, btime, txs, btxs, json.dumps(fvalue)))
return True
except:
return False
def checkPending(blocktxs):
#Check any pending tx to see if 1. They are in the current block of tx's we are processing or 2. 1 days have passed since broadcast and they are no longer in network.
#Remove them if either of these has happened
pendingtxs=dbSelect("select txhash,txdbserialnum,protocol,extract(epoch from txrecvtime) from transactions where txstate='pending' and txdbserialnum < 0")
for tx in pendingtxs:
txhash=tx[0]
txdbserialnum=tx[1]
protocol=tx[2]
#get an expiration time 7 days from now
#expire=int(time.time()) - 604466
#get an expiration time 12 hours from now
#expire=int(time.time()) - 43200
#get an expiration time 5 hours from now
expire=int(time.time()) - 18000
submitted=int(tx[3])
removeOld=False
if submitted < expire:
printdebug(("Found Pending TX, Age 5 hours:",txhash),5)
#we repopulate from client after so remove old txs
removeOld=True
#try:
# expiretx=getrawtransaction(txhash)
# if 'result' in expiretx:
# printdebug(("Pending TX still on network, skipping removal:",txhash),5)
# removeOld=False
#except Exception,e:
# printdebug(("Pending TX not on network, flagging removal:",txhash),5)
# removeOld=True
if txhash in blocktxs or removeOld:
#remove the pending item
if removeOld:
printdebug(("Removing Expired TX:",txhash,"from pending list"),4)
else:
printdebug(("Removing Confirmed TX:",txhash,"from pending list"),4)
#delete addressintx and transaction db entries
dbExecute("delete from addressesintxs where txdbserialnum=%s and protocol=%s", (txdbserialnum,protocol))
dbExecute("delete from transactions where txdbserialnum=%s and protocol=%s", (txdbserialnum,protocol))
dbExecute("delete from txjson where txdbserialnum=%s and protocol=%s", (txdbserialnum,protocol))
def clearPending():
dbExecute("delete from addressesintxs where txdbserialnum < 0")
dbExecute("delete from transactions where txdbserialnum < 0")
dbExecute("delete from txjson where txdbserialnum < 0")
def updateAddPending():
pendingList=omni_listpendingtransactions()
printdebug(("processing ",len(pendingList['result'])," pending transactions"),0)
counter=0
for rawtx in pendingList['result']:
try:
saddressrole="sender"
raddressrole="recipient"
sbacd=None
rbacd=None
sender = rawtx['sendingaddress']
try:
receiver = rawtx['referenceaddress']
except:
receiver=''
txtype = rawtx['type_int']
txversion = rawtx['version']
txhash = rawtx['txid']
TxClass = getTxClass(txhash)
#check if tx is already in db and skip
existing=dbSelect("select * from transactions where txhash=%s and protocol='Omni'",[txhash])
if len(existing) > 0:
continue
protocol = "Omni"
addresstxindex=0
txdbserialnum = dbSelect("select least(-1,min(txdbserialnum)) from transactions;")[0][0]
txdbserialnum -= 1
if txtype in [4]:
sendamount=None
recvamount=None
else:
propertyid = rawtx['propertyid'] if 'propertyid' in rawtx else rawtx['propertyidforsale']
if 'amount' in rawtx:
if rawtx['divisible']:
amount = int(decimal.Decimal(str(rawtx['amount']))*decimal.Decimal(1e8))
else:
amount = int(rawtx['amount'])
else:
if rawtx['propertyidforsaleisdivisible']:
amount = int(decimal.Decimal(str(rawtx['amountforsale']))*decimal.Decimal(1e8))
else:
amount = int(rawtx['amountforsale'])
if txtype in [26,55]:
#handle grants to ourself/others and cancel by price on OmniDex
if receiver == "":
sendamount=amount
recvamount=0
else:
sendamount=0
recvamount=amount
elif txtype == 22:
#sender = buyer
saddressrole="buyer"
sbacd=None
#receiver = seller
raddressrole="seller"
rbacd=amount
#unused in this tx
sendamount=None
recvamount=None
else:
#all other txs deduct from our balance and, where applicable, apply to the reciever
sendamount=-amount
recvamount=amount
address=sender
#insert the addressesintxs entry for the sender
dbExecute("insert into addressesintxs (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,balanceavailablecreditdebit,balanceacceptedcreditdebit) "
"values(%s,%s,%s,%s,%s,%s,%s,%s)", (address,propertyid,protocol,txdbserialnum,addresstxindex,saddressrole,sendamount,sbacd))
#update pending balance
#dbExecute("update addressbalances set balancepending=balancepending+%s::numeric where address=%s and propertyid=%s and protocol=%s", (sendamount,address,propertyid,protocol))
if receiver != "":
address=receiver
dbExecute("insert into addressesintxs (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,balanceavailablecreditdebit,balanceacceptedcreditdebit) "
"values(%s,%s,%s,%s,%s,%s,%s,%s)", (address,propertyid,protocol,txdbserialnum,addresstxindex,raddressrole,recvamount,rbacd))
#update pending balance
#dbExecute("update addressbalances set balancepending=balancepending+%s::numeric where address=%s and propertyid=%s and protocol=%s", (recvamount,address,propertyid,protocol))
dbExecute("insert into transactions (txhash,protocol,txdbserialnum,txtype,txversion,TxClass) values(%s,%s,%s,%s,%s,%s)",
(txhash,protocol,txdbserialnum,txtype,txversion,TxClass))
#store decoded omni data until tx confirms
dbExecute("insert into txjson (txdbserialnum, protocol, txdata) values (%s,%s,%s)", (txdbserialnum, protocol, json.dumps(rawtx)) )
counter+=1
except Exception,e:
print "Error: ", e, "\n Could not add OMNI PendingTx: ", rawtx
printdebug(("added ",counter," pending txs to db"),0)
def keyByAddress(item):
return item[0]
def keyByAmount(item):
return item[1]
def sortSTO(list):
#First, sort by Address alphabetically
list=sorted(list, key=keyByAddress)
#Second, sort by the amount. Largest to smallest
list=sorted(list, key=keyByAmount, reverse=True)
return list
def sendToOwners(Sender, Amount, PropertyID, Protocol, TxDBSerialNum, owners=None):
printdebug(("Starting sendToOwners:"),8)
printdebug(("Sender, Amount, PropertyID, Protocol, TxDBSerialNum, owners"),9)
printdebug((Sender, Amount, PropertyID, Protocol, TxDBSerialNum, owners, "\n"),9)
if owners == None:
#get list of owners sorted by most held to least held and by address alphabetically
owners=sortSTO(dbSelect("select address, balanceavailable from addressbalances where balanceavailable > 0 "
"and address != %s and propertyid=%s", (Sender, PropertyID)))
else:
#use the addresslist sent to us
owners=sortSTO(owners)
#find out how much is actually owned/held in total
toDistribute=Amount
sumTotal=sum([holder[1] for holder in owners])
#prime first position and set role
AddressTxIndex=0
AddressRole='payee'
Ecosystem=getEcosystem(PropertyID)
LastHash=gettxhash(TxDBSerialNum)
#process all holders from the sorted ownerslist
for holder in owners:
#who gets it
Address=holder[0]
#calculate percentage owed to the holder rounding up always
amountToSend=int( math.ceil((holder[1]/sumTotal) * Amount))
#if we sent this amount how much will we have left to send after (used to validate later)
remaining = toDistribute-amountToSend
#make sure its a valid amount to send
if amountToSend > 0:
#make sure amountToSend is actually available
if remaining >= 0:
#send/credit amountToSend to the holder
amountSent=amountToSend
else:
#send/credit whatever is left (toDistribute) to the holder
amountSent=toDistribute
#Insert the amountSent record into the addressesintx table?
dbExecute("insert into addressesintxs "
"(Address, PropertyID, Protocol, TxDBSerialNum, AddressTxIndex, AddressRole, BalanceAvailableCreditDebit)"
"values(%s, %s, %s, %s, %s, %s, %s)",
(Address, PropertyID, Protocol, TxDBSerialNum, AddressTxIndex, AddressRole, amountSent))
#update balance table
updateBalance(Address, Protocol, PropertyID, Ecosystem, amountSent, None, None, TxDBSerialNum)
#make sure we keep track of how much was sent/left to send
toDistribute-=amountSent
#/end if amountToSend > 0
#relative position of the recipiant
AddressTxIndex+=1
#no money left to distribute. Done
if toDistribute == 0:
break
#/end for holder in owners
def expireAccepts(Block):
printdebug(("Starting expireAccepts: ", Block),8)
if Block < 0 :
#reorg undo expire
#find the offers that are ready to expire and credit the 'accepted' amount back to the sellers sale
expiring=dbSelect("select oa.amountaccepted, oa.saletxdbserialnum, ao.offerstate from offeraccepts as oa, activeoffers as ao "
"where oa.saletxdbserialnum=ao.createtxdbserialnum and oa.expireblock >= %s and oa.expiredstate=true and "
"(oa.dexstate='paid-partial' or oa.dexstate='unpaid')", [-Block] )
else:
#find the offers that are ready to expire and credit the 'accepted' amount back to the sellers sale
expiring=dbSelect("select oa.amountaccepted, oa.saletxdbserialnum, ao.offerstate from offeraccepts as oa, activeoffers as ao "
"where oa.saletxdbserialnum=ao.createtxdbserialnum and oa.expireblock <= %s and oa.expiredstate=false and "
"(oa.dexstate='paid-partial' or oa.dexstate='unpaid')", [Block] )
#make sure we process all the offers that are expiring
for offer in expiring:
#only process if there is anything to process
if Block < 0:
#invert our calculations to work the reorg backwards
amountaccepted=offer[0]*-1
else:
amountaccepted=offer[0]
saletxserialnum=offer[1]
salestate=offer[2]
dbExecute("update activeoffers set amountaccepted=amountaccepted-%s::numeric, amountavailable=amountavailable+%s::numeric "
"where createtxdbserialnum=%s", (amountaccepted, amountaccepted, saletxserialnum) )
if salestate=='replaced' or salestate=='cancelled':
printdebug(("Found replaced/expired sale",saletxserialnum,"for expiring accept with amount",amountaccepted),4)
#sale ended credit the expired accepts' amount back to the users available balance and deduct it from the reserved/accepted balances
dbExecute("update addressbalances as ab set balanceavailable=ab.balanceavailable+%s::numeric, "
"balancereserved=ab.balancereserved-%s::numeric, balanceaccepted=ab.balanceaccepted-%s::numeric "
"from activeoffers as ao where ab.address=ao.seller and "
"ab.propertyid = ao.propertyidselling and ao.createtxdbserialnum=%s",
(amountaccepted, amountaccepted, amountaccepted, saletxserialnum) )
else:
printdebug(("sale",saletxserialnum,"still active, crediting expired offer amount back"),4)
#Sale still active, use the offers that are ready to expire to update the sellers accepted balance (reserved reflects total unsold amount left)
dbExecute("update addressbalances as ab set balanceaccepted=ab.balanceaccepted-%s::numeric "
"from activeoffers as ao where ab.address=ao.seller and "
"ab.propertyid = ao.propertyidselling and ao.createtxdbserialnum=%s",
(amountaccepted, saletxserialnum) )
if Block < 0:
dbExecute("update offeraccepts set expiredstate=false where expireblock >= %s and expiredstate=true", [-Block] )
else:
#every block we check any 'active' accepts. If their expire block has passed, we set them expired
dbExecute("update offeraccepts set expiredstate=true where expireblock <= %s and expiredstate=false", [Block] )
def updateAccept(Buyer, Seller, AmountBought, PropertyIDBought, TxDBSerialNum):
printdebug(("Starting updateAccepts:"),8)
printdebug(("Buyer, Seller, AmountBought, PropertyIDBought, TxDBSerialNum"),9)
printdebug((Buyer, Seller, AmountBought, PropertyIDBought, TxDBSerialNum, "\n"),9)
#user has paid for their accept (either partially or in full) update accordingly.
#find the accept data for updating
#saletx=dbSelect("select max(oa.saletxdbserialnum) from offeraccepts as oa inner join activeoffers as ao "
# "on (oa.saletxdbserialnum=ao.createtxdbserialnum) "
# "where oa.buyer=%s and ao.seller=%s and ao.propertyidselling=%s and oa.expiredstate=false",
# (Buyer, Seller, PropertyIDBought) )
#saletxdbserialnum=saletx[0][0]
accept=dbSelect("select oa.amountaccepted, oa.amountpurchased, ao.amountaccepted, ao.amountavailable, ao.offerstate, oa.saletxdbserialnum, oa.linkedtxdbserialnum "
"from offeraccepts oa inner join activeoffers ao on (oa.saletxdbserialnum=ao.createtxdbserialnum) "
"where oa.buyer=%s and ao.seller=%s and ao.propertyidselling=%s "
"and oa.dexstate != 'invalid' and oa.dexstate != 'paid-complete' and oa.expiredstate=false",
(Buyer, Seller, PropertyIDBought) )
buyeraccepted = accept[0][0] - AmountBought
buyerpurchased= AmountBought + accept[0][1]
saletxdbserialnum = accept[0][5]
offertxdbserialnum = accept[0][6]
if buyeraccepted > 0:
dexstate = 'paid-partial'
else:
dexstate = 'paid-complete'
#can we have a negative amount accepted? bad math?
#update the buyers 'accept' in the offeraccepts table with the new data
dbExecute("update offeraccepts as oa set amountaccepted=%s, amountpurchased=%s, dexstate=%s "
"from activeoffers as ao where oa.saletxdbserialnum=ao.createtxdbserialnum and oa.buyer=%s and ao.seller=%s "
"and ao.propertyidselling=%s and ao.createtxdbserialnum=%s and oa.dexstate != 'invalid' and "
"oa.dexstate != 'paid-complete' and oa.expiredstate=false",
(buyeraccepted, buyerpurchased, dexstate, Buyer, Seller, PropertyIDBought, saletxdbserialnum) )
selleraccepted= accept[0][2] - AmountBought
selleravailable=accept[0][3]
if selleraccepted == 0 and selleravailable == 0:
offerstate='sold'
else:
offerstate=accept[0][4]
#update the sellers sale with the information from the buyers successful buy
dbExecute("update activeoffers as ao set amountaccepted=%s, offerstate=%s, lasttxdbserialnum=%s "
"from offeraccepts as oa where oa.saletxdbserialnum=ao.createtxdbserialnum "
"and oa.buyer=%s and ao.seller=%s and ao.propertyidselling=%s and ao.createtxdbserialnum=%s",
(selleraccepted, offerstate, TxDBSerialNum, Buyer, Seller, PropertyIDBought, saletxdbserialnum) )
return saletxdbserialnum,offertxdbserialnum
def offerAccept (rawtx, TxDBSerialNum, Block):
printdebug(("Starting offerAccept"),8)
printdebug(("rawtx, TxDBSerialNum, Block"),9)
printdebug((rawtx, TxDBSerialNum, Block, "\n"),9)
BuyerAddress=rawtx['result']['sendingaddress']
SellerAddress=rawtx['result']['referenceaddress']
#what did the user accept
propertyidbuying = rawtx['result']['propertyid']
#what are they going to have to pay/send to complete. (BTC for now until metadex launch)
propertyidpaying = 0
#was it a valid accept, we still insert invalids for displaying to user later
valid = rawtx['result']['valid']
#convert accepted amount to non divisible quantity to store in db
#if rawtx['result']['divisible']:
if getDivisible(rawtx):
amountaccepted=int(decimal.Decimal(str(rawtx['result']['amount']))*decimal.Decimal(1e8))
else:
amountaccepted=int(rawtx['result']['amount'])
#get the current active dex sale this matches,
saleinfo=dbSelect("select createtxdbserialnum,timelimit,amountaccepted,amountavailable from activeoffers where seller=%s and offerstate='active'"
" and propertyidselling=%s and propertyiddesired=%s",
(SellerAddress, propertyidbuying, propertyidpaying) )
#catch/check if there is a valid sale it's trying to lookup, we can still attribute invalid tx's to the sale they tried to buy
if len(saleinfo) > 0:
saletxdbserialnum=saleinfo[0][0]
else:
saletxdbserialnum=-1
if valid:
#how long does user have to pay
timelimit=saleinfo[0][1]
#how much in the sale is currently accepted
currentamountaccepted=saleinfo[0][2]
amountavailable=saleinfo[0][3]
#calculate when the offer should expire
expireblock=timelimit+Block
dexstate='unpaid'
expiredstate='false'
#update original sale to reflect accept
currentamountaccepted+=amountaccepted
amountavailable-=amountaccepted
dbExecute("update activeoffers set amountaccepted=%s, amountavailable=%s, lasttxdbserialnum=%s where seller=%s and offerstate='active' and propertyidselling=%s and propertyiddesired=%s",
(currentamountaccepted,amountavailable,TxDBSerialNum,SellerAddress,propertyidbuying,propertyidpaying) )
else:
dexstate='invalid'
expiredstate='true'
expireblock=-1
#insert the offer
dbExecute("insert into offeraccepts (buyer, amountaccepted, linkedtxdbserialnum, saletxdbserialnum, block, dexstate, expireblock, expiredstate) "
"values(%s,%s,%s,%s,%s,%s,%s,%s)",
(BuyerAddress, amountaccepted, TxDBSerialNum, saletxdbserialnum, Block, dexstate, expireblock,expiredstate) )
def updatedex(rawtx, TxDBSerialNum, Protocol):
printdebug(("Starting updatedex"),8)
printdebug(("rawtx, TxDBSerialNum, Protocol"),9)
printdebug((rawtx, TxDBSerialNum, Protocol, "\n"),9)
Address=rawtx['result']['sendingaddress']
propertyiddesired=0
propertyidselling=rawtx['result']['propertyid']
if getdivisible_MP(propertyidselling):
amountavailable=int(decimal.Decimal(str(rawtx['result']['amount']))*decimal.Decimal(1e8))
else:
amountavailable=int(rawtx['result']['amount'])
#work around for some dex tx's not having a subaction
if 'subaction' in rawtx['result']:
subaction=rawtx['result']['subaction']
elif 'action' in rawtx['result']:
subaction=rawtx['result']['action']
elif amountavailable == 0:
subaction='cancel'
else:
subaction='new'
#find any balances left in the active sales to credit back to user
remaining=dbSelect("select amountavailable,createtxdbserialnum from activeoffers where seller=%s and offerstate='active' and propertyiddesired=%s and propertyidselling=%s",
( Address, propertyiddesired, propertyidselling) )
if remaining != []:
amount=remaining[0][0]
createtxdbserialnum=remaining[0][1]
else:
amount=None
createtxdbserialnum=None
#Catches, new, update, empty, cancel states from core
if subaction.lower() == 'cancel':
State='cancelled'
#Update any active offers to replace
dbExecute("update activeoffers set offerstate=%s, LastTxDBSerialNum=%s where seller=%s and offerstate='active' and propertyiddesired=%s and propertyidselling=%s",
(State, TxDBSerialNum, Address, propertyiddesired, propertyidselling) )
#debug statements
printdebug("cancelling any active offers for :", 4)
printdebug("State, TxDBSerialNum, Address, propertyiddesired, propertyidselling",4)
printdebug((State, TxDBSerialNum, Address, propertyiddesired, propertyidselling),4)
if amount != None:
printdebug(("found old sale",createtxdbserialnum,"with amount remaining",amount),4)
#we'll let the insertaddressintx function handle updating the balanace for cancels
return amount,createtxdbserialnum,State
else:
#state new/update
State='replaced'
#Update any active offers to replace
dbExecute("update activeoffers set offerstate=%s, LastTxDBSerialNum=%s where seller=%s and offerstate='active' and propertyiddesired=%s and propertyidselling=%s",
(State, TxDBSerialNum, Address, propertyiddesired, propertyidselling) )
if amount != None:
printdebug(("replacing old sale",createtxdbserialnum,"with amount remaining",amount,"with newsale",TxDBSerialNum),4)
#return the amount available/not accepted to users Available balance
BalanceAvailable=amount
#deduct whats left from the Reserved balanace (should be all unless there is an outstanding accept)
BalanceReserved=amount*-1
#we don't modify any current accepts,
BalanceAccepted=None
Ecosystem=getEcosystem(propertyidselling)
#credit any existing balances found for a 'replaced tx' back to seller since its about to have a new one
updateBalance(Address, Protocol, propertyidselling, Ecosystem, BalanceAvailable, BalanceReserved, BalanceAccepted, TxDBSerialNum)
#insert the new/updated tx as active
State='active'
amountaccepted=0
totalselling=amountavailable
#convert all btc stuff, need additional logic for metadex
amountdesired=int(decimal.Decimal(str(rawtx['result']['bitcoindesired']))*decimal.Decimal(1e8))
minimumfee=int(decimal.Decimal(str(rawtx['result']['feerequired']))*decimal.Decimal(1e8))
#rawtx does't have ppc, do the calculation to store
unitprice=int(amountdesired/amountavailable)
timelimit=rawtx['result']['timelimit']
dbExecute("insert into activeoffers (amountaccepted, amountavailable, totalselling, amountdesired, minimumfee, propertyidselling, "
"propertyiddesired, seller, timelimit, createtxdbserialnum, unitprice, offerstate) values "
"(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)",
(amountaccepted, amountavailable, totalselling, amountdesired, minimumfee, propertyidselling,
propertyiddesired, Address, timelimit, TxDBSerialNum, unitprice, State) )
return None,createtxdbserialnum,State
def updatedex2(rawtx, rawtrade, TxDBSerialNum):
printdebug(("Starting updatedex2"),8)
printdebug(("rawtx, rawtrade, TxDBSerialNum"),9)
printdebug((rawtx, rawtrade, TxDBSerialNum, "\n"),9)
Address=rawtx['result']['sendingaddress']
propertyiddesired=rawtx['result']['propertyiddesired']
propertyidselling=rawtx['result']['propertyidforsale']
saletxdbserial=gettxdbserialnum(rawtrade['result']['txid'],TxDBSerialNum)
txtype=rawtx['result']['type_int']
if txtype == 25:
#insert the new/updated tx
#State='active'
txstatus=rawtrade['result']['status']
if txstatus.lower() in ['open','open part filled']:
State='active'
elif txstatus.lower() == 'filled':
State='sold'
rawtrade['result']['amountremaining'] = 0
rawtrade['result']['amounttofill'] = 0
elif txstatus.lower() in ['cancelled','cancelled part filled']:
State='cancelled'
rawtrade['result']['amountremaining'] = 0
rawtrade['result']['amounttofill'] = 0
amountaccepted=0
if rawtx['result']['propertyidforsaleisdivisible']:
totalselling=int(decimal.Decimal(str(rawtx['result']['amountforsale']))*decimal.Decimal(1e8))
amountavailable=int(decimal.Decimal(str(rawtrade['result']['amountremaining']))*decimal.Decimal(1e8))
else:
totalselling=int(rawtx['result']['amountforsale'])
amountavailable=int(rawtrade['result']['amountremaining'])
if rawtx['result']['propertyiddesiredisdivisible']:
amountdesired=int(decimal.Decimal(str(rawtrade['result']['amounttofill']))*decimal.Decimal(1e8))
else:
amountdesired=int(rawtrade['result']['amounttofill'])
#convert all btc stuff, need additional logic for metadex
#minimumfee=int(decimal.Decimal(str(rawtx['result']['fee']))*decimal.Decimal(1e8))
#no min fee for dex 2.0
minimumfee=0
unitprice=rawtx['result']['unitprice']
timelimit=0
#dbExecute("insert into activeoffers (amountaccepted, amountavailable, totalselling, amountdesired, minimumfee, propertyidselling, "
# "propertyiddesired, seller, createtxdbserialnum, unitprice, offerstate, timelimit) values "
# "(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)",
# (amountaccepted, amountavailable, totalselling, amountdesired, minimumfee, propertyidselling,
# propertyiddesired, Address, TxDBSerialNum, unitprice, State, timelimit) )
dbExecute("with upsert as "
"(update activeoffers set offerstate=%s, LastTxDBSerialNum=%s, AmountAvailable=%s where seller=%s and "
"propertyiddesired=%s and propertyidselling=%s and CreateTxDBSerialNum=%s returning *) "
"insert into activeoffers (amountaccepted, amountavailable, totalselling, amountdesired, minimumfee, propertyidselling, "
"propertyiddesired, seller, createtxdbserialnum, unitprice, offerstate, timelimit) select %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s "
"where not exists (select * from upsert)",
(State, TxDBSerialNum, amountavailable, Address, propertyiddesired, propertyidselling, saletxdbserial,
amountaccepted, amountavailable, totalselling, amountdesired, minimumfee, propertyidselling,
propertyiddesired, Address, saletxdbserial, unitprice, State, timelimit) )
return
#elif txtype == 26:
#cancel by price
#elif txtype == 27:
#cancel by pair
#elif txtype == 28:
#cancel by ecosystem
def insertMatch(rawtrade, match, TxDBSerialNum):
txhash = rawtrade['result']['txid']
propertyidsold = rawtrade['result']['propertyidforsale']
propertyidreceived = rawtrade['result']['propertyiddesired']
amountsold = match['amountsold']
amountreceived = match['amountreceived']
block = match['block']
tradingfee = match['tradingfee']
matchedtxhash = match['txid']
dbExecute("insert into matchedtrades (txdbserialnum,txhash,propertyidsold,propertyidreceived,amountsold,amountreceived,block,tradingfee,matchedtxhash) "
"values (%s,%s,%s,%s,%s,%s,%s,%s,%s)",
(TxDBSerialNum,txhash,propertyidsold,propertyidreceived,amountsold,amountreceived,block,tradingfee,matchedtxhash) )
def updatemarketvolume():
ROWS=dbSelect("select COALESCE(sum(balanceavailablecreditdebit),0) from transactions tx, addressesintxs atx where "
"tx.txdbserialnum=atx.txdbserialnum and tx.txstate='valid' and tx.txtype=25 and "
"tx.txrecvtime>(CURRENT_TIMESTAMP - INTERVAL '1 day') and atx.addressrole='buyer' and atx.propertyid=%s")
def updatemarkets(propertyidselling,propertyiddesired,TxDBSerialNum, rawtx):
printdebug(("Starting updatemarkets"),4)
printdebug(("updatemarkets: propertyidselling,propertyiddesired,TxDBSerialNum"),4)
printdebug((propertyidselling,propertyiddesired,TxDBSerialNum),4)
printdebug(("updatemarkets: rawtx"),8)
printdebug((rawtx),8)
#base = propertyiddesired
#marketid = propertyidselling
lasttxdbserialnum = TxDBSerialNum
lastupdated=datetime.datetime.utcfromtimestamp(rawtx['result']['blocktime'])
SUP = dbSelect("select sum(amountavailable) from activeoffers where offerstate='active' and propertyidselling=%s "
"and propertyiddesired=%s", (propertyidselling, propertyiddesired))
if len(SUP) > 0:
supply=SUP[0][0]
else:
supply=0
UPA = dbSelect("select min(unitprice) from activeoffers where offerstate='active' and propertyidselling=%s "
"and propertyiddesired=%s and amountavailable=totalselling", (propertyidselling, propertyiddesired))
if len(UPA) > 0:
unitprice=UPA[0][0]
else:
unitprice=0
UP = dbSelect("select amountdesired, amountavailable, totalselling, unitprice from activeoffers where offerstate='active' and propertyidselling=%s "
"and propertyiddesired=%s and amountavailable!=totalselling order by unitprice asc", (propertyidselling, propertyiddesired))
if len(UP) > 0:
for offer in UP:
if getdivisible_MP(propertyiddesired):
totaldesired = offer[0]
else:
totaldesired = int(decimal.Decimal(str(offer[0]))*decimal.Decimal(1e8))
if getdivisible_MP(propertyidselling):
availselling = int(offer[1])
totalselling = int(offer[2])
else:
availselling = int(decimal.Decimal(str(offer[1]))*decimal.Decimal(1e8))
totalselling = int(decimal.Decimal(str(offer[2]))*decimal.Decimal(1e8))
origprice = offer[3]
remaindesired = math.ceil(availselling*origprice)
if remaindesired > totaldesired:
remaindesired = totaldesired
efup = decimal.Decimal((round((decimal.Decimal(remaindesired)/decimal.Decimal(availselling))*decimal.Decimal(1e8))))/decimal.Decimal(1e8)
if efup < unitprice or unitprice in [0,None]:
unitprice=efup
lastprice = dbSelect("select unitprice from markets where propertyidselling=%s and propertyiddesired=%s ",(propertyidselling, propertyiddesired))
if len(lastprice) > 0:
lastprice=lastprice[0][0]
else:
lastprice=0
if supply==None:
supply=0
if unitprice==None:
unitprice=0
if lastprice==None:
lastprice=0
dbExecute("with upsert as "
"(update markets set unitprice=%s, supply=%s, lastprice=%s, LastTxDBSerialNum=%s, lastupdated=%s where propertyiddesired=%s and propertyidselling=%s returning *), "
"spd as "
"(select propertyname from smartproperties where propertyid=%s and protocol='Omni') "
"insert into markets (propertyiddesired, desiredname, propertyidselling, sellingname, unitprice, supply, lastprice, lasttxdbserialnum, lastupdated, marketpropertytype) "
"select %s,spd.propertyname,%s,sps.propertyname,%s,%s,%s,%s,%s,propertytype from smartproperties sps, spd where propertyid=%s and protocol='Omni' and not exists (select * from upsert)",
(unitprice, supply, lastprice, lasttxdbserialnum, lastupdated, propertyiddesired, propertyidselling,
propertyiddesired,
propertyiddesired, propertyidselling, unitprice, supply, lastprice, lasttxdbserialnum, lastupdated,
propertyidselling) )
dbExecute("with nulsert as "
"(select * from markets where propertyiddesired=%s and propertyidselling=%s), "
"spd as "
"(select propertyname from smartproperties where propertyid=%s and protocol='Omni') "
"insert into markets (propertyiddesired, desiredname, propertyidselling, sellingname, lasttxdbserialnum, lastupdated, marketpropertytype) "
"select %s,spd.propertyname,%s,sps.propertyname,%s,%s,propertytype from smartproperties sps, spd where propertyid=%s and protocol='Omni' and not exists (select * from nulsert)",
(propertyidselling, propertyiddesired,
propertyidselling,
propertyidselling, propertyiddesired, lasttxdbserialnum, lastupdated,
propertyiddesired) )
def updatedex2remaining(TxHash, TxDBSerialNum):
#activeoffers subtract amount from remaining amount in db table
printdebug(("Starting updatedex2remaining"),8)
rawtrade=gettrade(TxHash)
printdebug(("TxHash, TxDBSerialNum, rawtrade"),9)
printdebug((TxHash, TxDBSerialNum, rawtrade, "\n"),9)
txstatus=rawtrade['result']['status']
if txstatus.lower() in ['open','open part filled']:
State='active'
elif txstatus.lower() == 'filled':
State='sold'
rawtrade['result']['amountremaining']=0
elif txstatus.lower() in ['cancelled','cancelled part filled']:
State='cancelled'
rawtrade['result']['amountremaining']=0
if rawtrade['result']['propertyidforsaleisdivisible']:
amountavailable=int(decimal.Decimal(str(rawtrade['result']['amountremaining']))*decimal.Decimal(1e8))
else:
amountavailable=int(rawtrade['result']['amountremaining'])