From 386a7c513ba456794df136c666e7bfa0d514c18f Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 7 Jan 2015 17:55:08 -0600 Subject: [PATCH 01/41] Add decode MP api --- api/decode.py | 147 ++++++++++++++++++++++++++++++ etc/nginx/sites-available/default | 11 +++ 2 files changed, 158 insertions(+) create mode 100644 api/decode.py diff --git a/api/decode.py b/api/decode.py new file mode 100644 index 000000000..8962c7d30 --- /dev/null +++ b/api/decode.py @@ -0,0 +1,147 @@ +from flask import Flask, abort, json, jsonify +import hashlib +import pybitcointools +from decimal import * +from rpcclient import * + +app = Flask(__name__) +app.debug = True + +@app.route('/') +def decode(rawhex): + + transaction = decoderawtransaction(rawhex)['result'] + senders = getrawtransaction(transaction['vin'][0]['txid'])['result']['vout'][transaction['vin'][0]['vout']]['scriptPubKey']['addresses'] + reference = senders[0] + + #get all multisigs + multisig_output = [] + for output in transaction['vout']: + if output['scriptPubKey']['type'] == 'multisig': + multisig_output.append(output) #grab msigs + + #extract compressed keys + scriptkeys = [] + for output in multisig_output: #seqnums start at 1, so adjust range + split_script = output['scriptPubKey']['asm'].split(' ') + for val in split_script: + if len(val) == 66: + scriptkeys.append(val) + + #filter keys that are ref + nonrefkeys = [] + for compressedkey in scriptkeys: + if pybitcointools.pubtoaddr(compressedkey) not in senders : + nonrefkeys.append(compressedkey) + + max_seqnum = len(nonrefkeys) + sha_keys = [ hashlib.sha256(reference).digest().encode('hex').upper()] #first sha256 of ref addr, see class B for more info + for i in range(max_seqnum): + if i < (max_seqnum-1): + sha_keys.append(hashlib.sha256(sha_keys[i]).digest().encode('hex').upper()) #keep sha'ing to generate more packets + + pairs = [] + for i in range(len(nonrefkeys)): + pairs.append((nonrefkeys[i], sha_keys[i] )) + + packets = [] + for pair in pairs: + obpacket = pair[0].upper()[2:-2] + shaaddress = pair[1][:-2] + print 'Obfus/SHA', obpacket, shaaddress + datapacket = '' + for i in range(len(obpacket)): + if obpacket[i] == shaaddress[i]: + datapacket = datapacket + '0' + else: + bin_ob = int('0x' + obpacket[i], 16) + bin_sha = int('0x' + shaaddress[i], 16) + xored = hex(bin_ob ^ bin_sha)[2:].upper() + datapacket = datapacket + xored + packets.append(datapacket) + + long_packet = '' + for packet in packets: + print 'Decoded packet #' + str(packet[0:2]) + ' : ' + packet + long_packet += packet[2:] + + + retval = {"Error":"Can\'t decode tx"} + if long_packet[4:8] == '0032': + #Create Fixed Issuance + spare_bytes = ''.join(long_packet[22:]) + #DEBUG print spare_bytes.split('00') + len_var_fields = len(''.join(spare_bytes.split('00')[0:5])+'0000000000') + #DEBUG print len_var_fields, spare_bytes[len_var_fields:len_var_fields+16],spare_bytes + + retval = { 'TxVersion': int(long_packet[0:4],16), + 'TxType': int(long_packet[4:8],16), + 'Ecosystem': int(long_packet[8:10],16), + 'Property Type': int(long_packet[10:14],16), + 'Previous Property ID': int(long_packet[14:22],16), + 'Property Category': spare_bytes.split('00')[0].decode('hex'), + 'Property Subcategory': spare_bytes.split('00')[1].decode('hex'), + 'Property Name': spare_bytes.split('00')[2].decode('hex'), + 'Property URL': spare_bytes.split('00')[3].decode('hex'), + 'Property Data': ''.join(spare_bytes.split('00')[4]).decode('hex'), + 'Number of Properties: ': int(str(int(spare_bytes[len_var_fields:len_var_fields+16],16))) + } + + if long_packet[4:8] == '0033': + #Create Variable issuance (Crowdsale) + spare_bytes = ''.join(long_packet[22:]) + #DEBUG print spare_bytes.split('00') + len_var_fields = len(''.join(spare_bytes.split('00')[0:5])+'0000000000') + #DEBUG print len_var_fields, spare_bytes[len_var_fields:len_var_fields+16],spare_bytes + + retval = { 'TxVersion': int(long_packet[0:4],16), + 'TxType': int(long_packet[4:8],16), + 'Ecosystem': int(long_packet[8:10],16), + 'Property Type': int(long_packet[10:14],16), + 'Previous Property ID': int(long_packet[14:22],16), + 'Property Category': spare_bytes.split('00')[0].decode('hex'), + 'Property Subcategory': spare_bytes.split('00')[1].decode('hex'), + 'Property Name': spare_bytes.split('00')[2].decode('hex'), + 'Property URL': spare_bytes.split('00')[3].decode('hex'), + 'Property Data': ''.join(spare_bytes.split('00')[4]).decode('hex'), + 'Currency Identifier Desired': str(int(spare_bytes[len_var_fields:len_var_fields+8],16)), + 'Number of Properties': str(int(spare_bytes[len_var_fields+8:len_var_fields+8+16],16)), + 'Deadline': str(int(spare_bytes[len_var_fields+8+16:len_var_fields+8+16+16],16)), + 'Earlybird Bonus': str(int(spare_bytes[len_var_fields+8+16+16:len_var_fields+8+16+16+2],16)), + 'Percentage for Issuer': str(int(spare_bytes[len_var_fields+8+16+16+2:len_var_fields+8+16+16+2+2],16)) + } + + if long_packet[4:8] == '0000': + #simple send + retval = { 'TxVersion': int(long_packet[0:4],16), + 'TxType': int(long_packet[4:8],16), + 'Currency Identifier': int(long_packet[8:16],16), + 'Amount Transfered': int(long_packet[16:32],16) + } + + if long_packet[4:8] == '0035': + #Close Crowdsale Manually + retval = { 'TxVersion': int(long_packet[0:4],16), + 'TxType': int(long_packet[4:8],16), + 'Currency Identifier': int(long_packet[8:16],16) + } + + if long_packet[4:8] == '0037': + #grant properties + retval = { 'TxVersion': int(long_packet[0:4],16), + 'TxType': int(long_packet[4:8],16), + 'Currency Identifier': int(long_packet[8:16],16), + 'Amount Created': int(long_packet[16:32],16) + } + + if long_packet[4:8] == '0038': + #revoke properties + retval = { 'TxVersion': int(long_packet[0:4],16), + 'TxType': int(long_packet[4:8],16), + 'Currency Identifier': int(long_packet[8:16],16), + 'Amount Revoked': int(long_packet[16:32],16) + } + + print retval + return jsonify({'MP':retval,'BTC':transaction}) + diff --git a/etc/nginx/sites-available/default b/etc/nginx/sites-available/default index 58e7007a9..49a96c639 100644 --- a/etc/nginx/sites-available/default +++ b/etc/nginx/sites-available/default @@ -289,4 +289,15 @@ server { uwsgi_modifier1 30; uwsgi_pass 127.0.0.1:$PORT; } + + location = /v1/decode { rewrite ^ /v1/decode; } + location /v1/decode { try_files $uri @flask_decode; } + location @flask_decode { + include uwsgi_params; + uwsgi_param SCRIPT_NAME /v1/decode; + uwsgi_param UWSGI_MODULE decode; + uwsgi_param UWSGI_CALLABLE app; + uwsgi_modifier1 30; + uwsgi_pass 127.0.0.1:$PORT; + } } From 24840c871f6d62bf71d176930f90c7baeea75a99 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 8 Jan 2015 10:33:17 -0600 Subject: [PATCH 02/41] Update nginx config files --- etc/nginx/sites-available/README | 6 + etc/nginx/sites-available/default | 266 +---------------------- etc/nginx/sites-available/omni-redirects | 222 +++++++++++++++++++ 3 files changed, 236 insertions(+), 258 deletions(-) create mode 100644 etc/nginx/sites-available/README create mode 100644 etc/nginx/sites-available/omni-redirects diff --git a/etc/nginx/sites-available/README b/etc/nginx/sites-available/README new file mode 100644 index 000000000..8afa33186 --- /dev/null +++ b/etc/nginx/sites-available/README @@ -0,0 +1,6 @@ +Copy/install the 'default' file into yoru nginx/sites-available/ folder +Then modify/update it to fit your server setup. +There are 2 items that need to be updated at the bottom. +1. Points to the location of the omniwallet www folder +2. Points to the location of the omni-redirects file in this folder + This is the core of the API and has been abstracted out to allow easier updates in future. diff --git a/etc/nginx/sites-available/default b/etc/nginx/sites-available/default index 49a96c639..5d6665fc6 100644 --- a/etc/nginx/sites-available/default +++ b/etc/nginx/sites-available/default @@ -30,274 +30,24 @@ server { add_header Pragma "no-cache"; add_header Expires "0"; - ## Set this to reflect the location of the www directory within the omniwallet repo. - root /home/myUser/omniwallet/www/; - index index.htm index.html; - #enable gzip compression gzip on; gzip_min_length 20; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain application/xml application/x-javascript application/javascript text/css text/javascript text/html application/json; - #Re-route nested routed through index - location / { - try_files $uri $uri/ /index.html =404; - } - - location ~ "^/wallet/$" { - return 301 /wallet/overview; - } - - #Limit Perl Access per phil's recommendation - if ($http_user_agent ~ "libwww-perl.*"){ - return 403; - break; - } - # Make site accessible from http://localhost/ server_name localhost; - set $WEBSOCKET_PORT 1091; - location /socket.io { - proxy_pass http://127.0.0.1:1091/socket.io; - proxy_redirect off; - proxy_buffering off; - - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "Upgrade"; - } - - location ~ "^/v1/transaction/values.json$" { - alias /var/lib/omniwallet/www/values.json; - } - - location ~ "^/v1/system/stats.json$" { - #alias /var/lib/omniwallet/www/stats.json; - rewrite ^ /v1/system/stats; - - } - - location ~ "^/v1/system/status.html$" { - alias /var/lib/omniwallet/www/status.html; - } - - location ~ "^/v1/system/revision.json$" { - #alias /var/lib/omniwallet/www/revision.json; - rewrite ^ /v1/system/revision; - } - - location ~ "^/v1/exchange/offers/(.*)$" { - alias /var/lib/omniwallet/www/offers/$1; - } - - #location ~ "^/v1/transaction/general/(.*)$" { - # alias /var/lib/omniwallet/www/general/$1; - #} - - #location ~ "^/v1/transaction/tx/(.*)$" { - # alias /var/lib/omniwallet/www/tx/$1; - #} - - #location ~ "^/v1/property/([0-9]*.json)$" { - # add_header Access-Control-Allow-Origin *; - # alias /var/lib/omniwallet/www/properties/properties-$1; - #} - - #location ~ "^/v1/values/(.*)$" { - # add_header Access-Control-Allow-Origin *; - # alias /var/lib/omniwallet/www/values/$1; - #} - - #location ~ "^/v1/values/history/(.*)$" { - # alias /var/lib/omniwallet/www/values/history/$1; - #} - - #location ~ "^/v1/address/verify/(.*)$" { - # alias /var/lib/omniwallet/www/mastercoin_verify/addresses/$1; - #} - - #location ~ "^/v1/transaction/verify/(.*)$" { - # alias /var/lib/omniwallet/www/mastercoin_verify/transactions/$1; - #} + ############## + #### Update the two entries below and replace 'myUser' with the user omniwallet is installed under + ############## - include uwsgi_params; - uwsgi_param SCRIPT_NAME $app; - uwsgi_param UWSGI_MODULE $app; - uwsgi_param UWSGI_CALLABLE "${app}_handler"; - - set $PORT 1088; - location /v1/address/addr/ { - add_header Access-Control-Allow-Origin *; - set $app get_balance; - uwsgi_pass 127.0.0.1:$PORT; - } - - #location /v1/transaction/validateaddr/ { - # set $app validateaddr; - # uwsgi_pass 127.0.0.1:$PORT; - #} - - location /v1/transaction/send/ { - set $app send; - uwsgi_pass 127.0.0.1:$PORT; - } - - location /v1/exchange/sell/ { - set $app sell; - uwsgi_pass 127.0.0.1:$PORT; - } - - location /v1/exchange/accept/ { - set $app accept; - uwsgi_pass 127.0.0.1:$PORT; - } - - location /v1/transaction/pushtx/ { - set $app pushtx; - uwsgi_pass 127.0.0.1:$PORT; - } - - location /v1/exchange/offers { - set $app offers; - uwsgi_pass 127.0.0.1:$PORT; - } - - location = /v1/user/wallet { rewrite ^ /v1/user/wallet/; } - location /v1/user/wallet { try_files $uri @flask_user_service; } - location @flask_user_service { - include uwsgi_params; - uwsgi_param SCRIPT_NAME /v1/user/wallet; - uwsgi_param UWSGI_MODULE user_service; - uwsgi_param UWSGI_CALLABLE app; - uwsgi_modifier1 30; - uwsgi_pass 127.0.0.1:$PORT; - } - - location = /v1/properties { rewrite ^ /v1/properties/; } - location /v1/properties { try_files $uri @flask_properties_service; } - location @flask_properties_service { - include uwsgi_params; - uwsgi_param SCRIPT_NAME /v1/properties; - uwsgi_param UWSGI_MODULE properties_service; - uwsgi_param UWSGI_CALLABLE app; - uwsgi_modifier1 30; - uwsgi_pass 127.0.0.1:$PORT; - } - - location = /v1/property { rewrite ^ /v1/property/; } - location /v1/property { try_files $uri @flask_property_service; } - location @flask_property_service { - include uwsgi_params; - uwsgi_param SCRIPT_NAME /v1/property; - uwsgi_param UWSGI_MODULE property_service; - uwsgi_param UWSGI_CALLABLE app; - uwsgi_modifier1 30; - uwsgi_pass 127.0.0.1:$PORT; - } - - location = /v1/transaction { rewrite ^ /v1/transaction; } - location /v1/transaction { try_files $uri @flask_transaction_service; } - location @flask_transaction_service { - include uwsgi_params; - uwsgi_param SCRIPT_NAME /v1/transaction; - uwsgi_param UWSGI_MODULE transaction_service; - uwsgi_param UWSGI_CALLABLE app; - uwsgi_modifier1 30; - uwsgi_pass 127.0.0.1:$PORT; - } - - location = /v1/mastercoin_verify { rewrite ^ /v1/mastercoin_verify/; } - location /v1/mastercoin_verify { try_files $uri @flask_mastercoin_verify; } - location @flask_mastercoin_verify { - include uwsgi_params; - uwsgi_param SCRIPT_NAME /v1/mastercoin_verify; - uwsgi_param UWSGI_MODULE mastercoin_verify; - uwsgi_param UWSGI_CALLABLE app; - uwsgi_modifier1 30; - uwsgi_pass 127.0.0.1:$PORT; - } - - location = /v1/transaction/getunsigned { rewrite ^ /v1/transaction/getunsigned; } - location /v1/transaction/getunsigned { try_files $uri @flask_tx_generate_service; } - location @flask_tx_generate_service { - include uwsgi_params; - uwsgi_param SCRIPT_NAME /v1/transaction/getunsigned; - uwsgi_param UWSGI_MODULE tx_generate_service; - uwsgi_param UWSGI_CALLABLE app; - uwsgi_modifier1 30; - uwsgi_pass 127.0.0.1:$PORT; - } - - location = /v1/armory { rewrite ^ /v1/armory; } - location /v1/armory { try_files $uri @flask_armory_service; } - location @flask_armory_service { - include uwsgi_params; - uwsgi_param SCRIPT_NAME /v1/armory; - uwsgi_param UWSGI_MODULE armory_service; - uwsgi_param UWSGI_CALLABLE app; - uwsgi_modifier1 30; - uwsgi_pass 127.0.0.1:$PORT; - } - - - location = /v1/search { rewrite ^ /v1/search; } - location /v1/search { try_files $uri @flask_search_service; } - location @flask_search_service { - include uwsgi_params; - uwsgi_param SCRIPT_NAME /v1/search; - uwsgi_param UWSGI_MODULE search_service; - uwsgi_param UWSGI_CALLABLE app; - uwsgi_modifier1 30; - uwsgi_pass 127.0.0.1:$PORT; - } - - location = /v1/blocks { rewrite ^ /v1/blocks/; } - location /v1/blocks { try_files $uri @flask_getblocks; } - location @flask_getblocks { - include uwsgi_params; - uwsgi_param SCRIPT_NAME /v1/blocks; - uwsgi_param UWSGI_MODULE getblocks; - uwsgi_param UWSGI_CALLABLE app; - uwsgi_modifier1 30; - uwsgi_pass 127.0.0.1:$PORT; - } - - location = /v1/system { rewrite ^ /v1/system; } - location /v1/system { try_files $uri @flask_stats_service; } - location @flask_stats_service { - include uwsgi_params; - uwsgi_param SCRIPT_NAME /v1/system; - uwsgi_param UWSGI_MODULE stats_service; - uwsgi_param UWSGI_CALLABLE app; - uwsgi_modifier1 30; - uwsgi_pass 127.0.0.1:$PORT; - } + ## Set this to reflect the location of the www directory within the omniwallet repo. + root /home/myUser/omniwallet/www/; + index index.htm index.html; - location = /v1/values { rewrite ^ /v1/values; } - location /v1/values { try_files $uri @flask_values_service; } - location @flask_values_service { - include uwsgi_params; - uwsgi_param SCRIPT_NAME /v1/values; - uwsgi_param UWSGI_MODULE values_service; - uwsgi_param UWSGI_CALLABLE app; - uwsgi_modifier1 30; - uwsgi_pass 127.0.0.1:$PORT; - } + ## Set this to reflect the location of the omni-redirects file within the omniwallet repo + include /home/myUser/omniwallet/etc/nginx/sites-available/omni-redirects; - location = /v1/decode { rewrite ^ /v1/decode; } - location /v1/decode { try_files $uri @flask_decode; } - location @flask_decode { - include uwsgi_params; - uwsgi_param SCRIPT_NAME /v1/decode; - uwsgi_param UWSGI_MODULE decode; - uwsgi_param UWSGI_CALLABLE app; - uwsgi_modifier1 30; - uwsgi_pass 127.0.0.1:$PORT; - } } diff --git a/etc/nginx/sites-available/omni-redirects b/etc/nginx/sites-available/omni-redirects new file mode 100644 index 000000000..2c518f668 --- /dev/null +++ b/etc/nginx/sites-available/omni-redirects @@ -0,0 +1,222 @@ + #Re-route nested routed through index + location / { + try_files $uri $uri/ /index.html =404; + } + + location ~ "^/wallet/$" { + return 301 /wallet/overview; + } + + #Limit Perl Access per phil's recommendation + if ($http_user_agent ~ "libwww-perl.*"){ + return 403; + break; + } + + set $WEBSOCKET_PORT 1091; + location /socket.io { + proxy_pass http://127.0.0.1:1091/socket.io; + proxy_redirect off; + proxy_buffering off; + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + } + + location ~ "^/v1/transaction/values.json$" { + alias /var/lib/omniwallet/www/values.json; + } + + location ~ "^/v1/system/stats.json$" { + #alias /var/lib/omniwallet/www/stats.json; + rewrite ^ /v1/system/stats; + + } + + location ~ "^/v1/system/status.html$" { + alias /var/lib/omniwallet/www/status.html; + } + + location ~ "^/v1/system/revision.json$" { + #alias /var/lib/omniwallet/www/revision.json; + rewrite ^ /v1/system/revision; + } + + location ~ "^/v1/exchange/offers/(.*)$" { + alias /var/lib/omniwallet/www/offers/$1; + } + + include uwsgi_params; + uwsgi_param SCRIPT_NAME $app; + uwsgi_param UWSGI_MODULE $app; + uwsgi_param UWSGI_CALLABLE "${app}_handler"; + + set $PORT 1088; + location /v1/address/addr/ { + add_header Access-Control-Allow-Origin *; + set $app get_balance; + uwsgi_pass 127.0.0.1:$PORT; + } + + location /v1/transaction/send/ { + set $app send; + uwsgi_pass 127.0.0.1:$PORT; + } + + location /v1/exchange/sell/ { + set $app sell; + uwsgi_pass 127.0.0.1:$PORT; + } + + location /v1/exchange/accept/ { + set $app accept; + uwsgi_pass 127.0.0.1:$PORT; + } + + location /v1/transaction/pushtx/ { + set $app pushtx; + uwsgi_pass 127.0.0.1:$PORT; + } + + location /v1/exchange/offers { + set $app offers; + uwsgi_pass 127.0.0.1:$PORT; + } + + location = /v1/user/wallet { rewrite ^ /v1/user/wallet/; } + location /v1/user/wallet { try_files $uri @flask_user_service; } + location @flask_user_service { + include uwsgi_params; + uwsgi_param SCRIPT_NAME /v1/user/wallet; + uwsgi_param UWSGI_MODULE user_service; + uwsgi_param UWSGI_CALLABLE app; + uwsgi_modifier1 30; + uwsgi_pass 127.0.0.1:$PORT; + } + + location = /v1/properties { rewrite ^ /v1/properties/; } + location /v1/properties { try_files $uri @flask_properties_service; } + location @flask_properties_service { + include uwsgi_params; + uwsgi_param SCRIPT_NAME /v1/properties; + uwsgi_param UWSGI_MODULE properties_service; + uwsgi_param UWSGI_CALLABLE app; + uwsgi_modifier1 30; + uwsgi_pass 127.0.0.1:$PORT; + } + + location = /v1/property { rewrite ^ /v1/property/; } + location /v1/property { try_files $uri @flask_property_service; } + location @flask_property_service { + include uwsgi_params; + uwsgi_param SCRIPT_NAME /v1/property; + uwsgi_param UWSGI_MODULE property_service; + uwsgi_param UWSGI_CALLABLE app; + uwsgi_modifier1 30; + uwsgi_pass 127.0.0.1:$PORT; + } + + location = /v1/transaction { rewrite ^ /v1/transaction; } + location /v1/transaction { try_files $uri @flask_transaction_service; } + location @flask_transaction_service { + include uwsgi_params; + uwsgi_param SCRIPT_NAME /v1/transaction; + uwsgi_param UWSGI_MODULE transaction_service; + uwsgi_param UWSGI_CALLABLE app; + uwsgi_modifier1 30; + uwsgi_pass 127.0.0.1:$PORT; + } + + location = /v1/mastercoin_verify { rewrite ^ /v1/mastercoin_verify/; } + location /v1/mastercoin_verify { try_files $uri @flask_mastercoin_verify; } + location @flask_mastercoin_verify { + include uwsgi_params; + uwsgi_param SCRIPT_NAME /v1/mastercoin_verify; + uwsgi_param UWSGI_MODULE mastercoin_verify; + uwsgi_param UWSGI_CALLABLE app; + uwsgi_modifier1 30; + uwsgi_pass 127.0.0.1:$PORT; + } + + location = /v1/transaction/getunsigned { rewrite ^ /v1/transaction/getunsigned; } + location /v1/transaction/getunsigned { try_files $uri @flask_tx_generate_service; } + location @flask_tx_generate_service { + include uwsgi_params; + uwsgi_param SCRIPT_NAME /v1/transaction/getunsigned; + uwsgi_param UWSGI_MODULE tx_generate_service; + uwsgi_param UWSGI_CALLABLE app; + uwsgi_modifier1 30; + uwsgi_pass 127.0.0.1:$PORT; + } + + location = /v1/armory { rewrite ^ /v1/armory; } + location /v1/armory { try_files $uri @flask_armory_service; } + location @flask_armory_service { + include uwsgi_params; + uwsgi_param SCRIPT_NAME /v1/armory; + uwsgi_param UWSGI_MODULE armory_service; + uwsgi_param UWSGI_CALLABLE app; + uwsgi_modifier1 30; + uwsgi_pass 127.0.0.1:$PORT; + } + + + location = /v1/search { rewrite ^ /v1/search; } + location /v1/search { try_files $uri @flask_search_service; } + location @flask_search_service { + include uwsgi_params; + uwsgi_param SCRIPT_NAME /v1/search; + uwsgi_param UWSGI_MODULE search_service; + uwsgi_param UWSGI_CALLABLE app; + uwsgi_modifier1 30; + uwsgi_pass 127.0.0.1:$PORT; + } + + location = /v1/blocks { rewrite ^ /v1/blocks/; } + location /v1/blocks { try_files $uri @flask_getblocks; } + location @flask_getblocks { + include uwsgi_params; + uwsgi_param SCRIPT_NAME /v1/blocks; + uwsgi_param UWSGI_MODULE getblocks; + uwsgi_param UWSGI_CALLABLE app; + uwsgi_modifier1 30; + uwsgi_pass 127.0.0.1:$PORT; + } + + location = /v1/system { rewrite ^ /v1/system; } + location /v1/system { try_files $uri @flask_stats_service; } + location @flask_stats_service { + include uwsgi_params; + uwsgi_param SCRIPT_NAME /v1/system; + uwsgi_param UWSGI_MODULE stats_service; + uwsgi_param UWSGI_CALLABLE app; + uwsgi_modifier1 30; + uwsgi_pass 127.0.0.1:$PORT; + } + + location = /v1/values { rewrite ^ /v1/values; } + location /v1/values { try_files $uri @flask_values_service; } + location @flask_values_service { + include uwsgi_params; + uwsgi_param SCRIPT_NAME /v1/values; + uwsgi_param UWSGI_MODULE values_service; + uwsgi_param UWSGI_CALLABLE app; + uwsgi_modifier1 30; + uwsgi_pass 127.0.0.1:$PORT; + } + + location = /v1/decode { rewrite ^ /v1/decode; } + location /v1/decode { try_files $uri @flask_decode; } + location @flask_decode { + include uwsgi_params; + uwsgi_param SCRIPT_NAME /v1/decode; + uwsgi_param UWSGI_MODULE decode; + uwsgi_param UWSGI_CALLABLE app; + uwsgi_modifier1 30; + uwsgi_pass 127.0.0.1:$PORT; + } From f90da6361b4db1841307c1f2e51b83f2b4a63137 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 8 Jan 2015 16:19:56 -0600 Subject: [PATCH 03/41] Insert Pendingtx into db --- api/decode.py | 54 +++++++++++++++++++++++++++++++++++++++++--------- api/pending.py | 44 ++++++++++++++++++++++++++++++++++++++++ api/pushtx.py | 5 +++++ 3 files changed, 94 insertions(+), 9 deletions(-) create mode 100644 api/pending.py diff --git a/api/decode.py b/api/decode.py index 8962c7d30..65c1a24a9 100644 --- a/api/decode.py +++ b/api/decode.py @@ -16,9 +16,17 @@ def decode(rawhex): #get all multisigs multisig_output = [] + dest="" for output in transaction['vout']: if output['scriptPubKey']['type'] == 'multisig': multisig_output.append(output) #grab msigs + else: + try: + for address in output['scriptPubKey']['addresses']: + if address not in (['1EXoDusjGwvnjZUyKkxZ4UHEf77z6A5S4P','mpexoDuSkGGqvqrkrjiFng38QPkJQVFyqv']+senders): + dest=output['scriptPubKey']['addresses'][0] + except KeyError: + pass #extract compressed keys scriptkeys = [] @@ -76,6 +84,7 @@ def decode(rawhex): retval = { 'TxVersion': int(long_packet[0:4],16), 'TxType': int(long_packet[4:8],16), + 'TxTypeString': 'Create Fixed Issuance', 'Ecosystem': int(long_packet[8:10],16), 'Property Type': int(long_packet[10:14],16), 'Previous Property ID': int(long_packet[14:22],16), @@ -96,6 +105,7 @@ def decode(rawhex): retval = { 'TxVersion': int(long_packet[0:4],16), 'TxType': int(long_packet[4:8],16), + 'TxTypeString': 'Create Variable Issuance (Crowdsale)', 'Ecosystem': int(long_packet[8:10],16), 'Property Type': int(long_packet[10:14],16), 'Previous Property ID': int(long_packet[14:22],16), @@ -104,7 +114,7 @@ def decode(rawhex): 'Property Name': spare_bytes.split('00')[2].decode('hex'), 'Property URL': spare_bytes.split('00')[3].decode('hex'), 'Property Data': ''.join(spare_bytes.split('00')[4]).decode('hex'), - 'Currency Identifier Desired': str(int(spare_bytes[len_var_fields:len_var_fields+8],16)), + 'PropertyID Desired': str(int(spare_bytes[len_var_fields:len_var_fields+8],16)), 'Number of Properties': str(int(spare_bytes[len_var_fields+8:len_var_fields+8+16],16)), 'Deadline': str(int(spare_bytes[len_var_fields+8+16:len_var_fields+8+16+16],16)), 'Earlybird Bonus': str(int(spare_bytes[len_var_fields+8+16+16:len_var_fields+8+16+16+2],16)), @@ -115,33 +125,59 @@ def decode(rawhex): #simple send retval = { 'TxVersion': int(long_packet[0:4],16), 'TxType': int(long_packet[4:8],16), - 'Currency Identifier': int(long_packet[8:16],16), - 'Amount Transfered': int(long_packet[16:32],16) + 'TxTypeString': 'Simple Send', + 'PropertyID': int(long_packet[8:16],16), + 'Amount': int(long_packet[16:32],16) + } + + if long_packet[4:8] == '0003': + #STO + retval = { 'TxVersion': int(long_packet[0:4],16), + 'TxType': int(long_packet[4:8],16), + 'TxTypeString': 'Send To Owners', + 'PropertyID': int(long_packet[8:16],16), + 'Amount': int(long_packet[16:32],16) + } + + if long_packet[4:8] == '0014': + #DEx Sell Offer + retval = { 'TxVersion': int(long_packet[0:4],16), + 'TxType': int(long_packet[4:8],16), + 'TxTypeString': 'DEx Sell Offer', + 'PropertyID': int(long_packet[8:16],16), + 'Amount': int(long_packet[16:32],16), + 'BTCDesired': int(long_packet[32:48],16), + 'TimePeriod': int(long_packet[48:50],16), + 'FeeRequired': int(long_packet[50:66],16), + 'Action': int(long_packet[66:68],16) } if long_packet[4:8] == '0035': #Close Crowdsale Manually retval = { 'TxVersion': int(long_packet[0:4],16), 'TxType': int(long_packet[4:8],16), - 'Currency Identifier': int(long_packet[8:16],16) + 'TxTypeString': 'Close Crowdsale Manually', + 'PropertyID': int(long_packet[8:16],16) } if long_packet[4:8] == '0037': #grant properties retval = { 'TxVersion': int(long_packet[0:4],16), 'TxType': int(long_packet[4:8],16), - 'Currency Identifier': int(long_packet[8:16],16), - 'Amount Created': int(long_packet[16:32],16) + 'TxTypeString': 'Grant Properties', + 'PropertyID': int(long_packet[8:16],16), + 'Amount': int(long_packet[16:32],16) } if long_packet[4:8] == '0038': #revoke properties retval = { 'TxVersion': int(long_packet[0:4],16), 'TxType': int(long_packet[4:8],16), - 'Currency Identifier': int(long_packet[8:16],16), - 'Amount Revoked': int(long_packet[16:32],16) + 'TxTypeString': 'Revoke Properties', + 'PropertyID': int(long_packet[8:16],16), + 'Amount': int(long_packet[16:32],16) } print retval - return jsonify({'MP':retval,'BTC':transaction}) + return jsonify({'Sender':reference,'Receiver':dest,'MP':retval,'BTC':transaction}) diff --git a/api/pending.py b/api/pending.py new file mode 100644 index 000000000..b47b97381 --- /dev/null +++ b/api/pending.py @@ -0,0 +1,44 @@ +from decode import * +from sqltools import * + +def insertpending(txhex): + + rawtx = decode(txhex) + if 'Amount' not in rawtx['MP'] and rawtx['MP']['Amount']<=0: + #only run if we have a non zero positive amount to process, otherwise exit + return + + sender = rawtx['Sender'] + reciever = rawtx['Reciever'] + propertyid = rawtx['MP']['PropertyID'] + txtype = rawtx['MP']['TxType'] + txversion = rawtx['MP']['TxVersion'] + txhash = rawtx['BTC']['txid'] + amount = rawtx['MP']['Amount'] + protocol = "Mastercoin" + + txdbserialnum = dbSelect("select least(-1,min(txdbserialnum)) from transactions;") + txdbserialnum -=1 + + + dbExecute("insert into transactions (txhash,protocol,txdbserialnum,txtype,txversion) values(%s,%s,%s,%s,%s)", + (txhash,protocol,txdbserialnum,txtype,txversion)) + + address=sender + addressrole="sender" + #insert the addressesintxs entry for the sender + dbExecute("insert into addressesintxs (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,balanceavailablecreditdebit) " + "values(%s,%s,%s,%s,%s,%s,%s,%s)", (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,-amount)) + + #update pending balance + dbExecute("update addressbalances set balancepending=balancepending-%s where address=%s and propertyid=%s and protocol=%s", (amount,address,protocol)) + + if reciever != "": + address=reciever + addressrole="reciever" + dbExecute("insert into addressesintxs (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,balanceavailablecreditdebit) " + "values(%s,%s,%s,%s,%s,%s,%s,%s)", (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,amount)) + #update pending balance + dbExecute("update addressbalances set balancepending=balancepending+%s where address=%s and propertyid=%s and protocol=%s", (amount,address,protocol)) + + diff --git a/api/pushtx.py b/api/pushtx.py index 254c055a4..30cd164c3 100644 --- a/api/pushtx.py +++ b/api/pushtx.py @@ -5,6 +5,7 @@ sys.path.append(lib_path) from msc_utils_parsing import * from msc_apps import * +from pending import * import tempfile sys.path.append(os.path.abspath("../lib")) @@ -41,6 +42,10 @@ def pushtx_response(response_dict): signed_tx=response_dict['signedTransaction'][0] response=pushtxnode(signed_tx) + + if "NOTOK" not in response['status']: + insertpending(signed_tx) + print signed_tx,'\n', response return (response, None) From e39d026607fd911c4768f0c9c8c238ffa9bbe0c4 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 8 Jan 2015 18:23:31 -0600 Subject: [PATCH 04/41] update pending logic for grants, fix missing variable definition --- api/pending.py | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/api/pending.py b/api/pending.py index b47b97381..2731439a2 100644 --- a/api/pending.py +++ b/api/pending.py @@ -14,12 +14,24 @@ def insertpending(txhex): txtype = rawtx['MP']['TxType'] txversion = rawtx['MP']['TxVersion'] txhash = rawtx['BTC']['txid'] - amount = rawtx['MP']['Amount'] protocol = "Mastercoin" - + addresstxindex=0 txdbserialnum = dbSelect("select least(-1,min(txdbserialnum)) from transactions;") - txdbserialnum -=1 - + txdbserialnum -= 1 + amount = rawtx['MP']['Amount'] + + if txtype == 55: + #handle grants to ourself or others + if reciever == "": + sendamount=amount + recvamount=0 + else: + sendamount=0 + recvamount=amount + else: + #all other txs deduct from our balance and, where applicable, apply to the reciever + sendamount=-amount + recvamount=amount dbExecute("insert into transactions (txhash,protocol,txdbserialnum,txtype,txversion) values(%s,%s,%s,%s,%s)", (txhash,protocol,txdbserialnum,txtype,txversion)) @@ -28,17 +40,17 @@ def insertpending(txhex): addressrole="sender" #insert the addressesintxs entry for the sender dbExecute("insert into addressesintxs (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,balanceavailablecreditdebit) " - "values(%s,%s,%s,%s,%s,%s,%s,%s)", (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,-amount)) + "values(%s,%s,%s,%s,%s,%s,%s,%s)", (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,sendamount)) #update pending balance - dbExecute("update addressbalances set balancepending=balancepending-%s where address=%s and propertyid=%s and protocol=%s", (amount,address,protocol)) + dbExecute("update addressbalances set balancepending=balancepending-%s where address=%s and propertyid=%s and protocol=%s", (sendamount,address,protocol)) if reciever != "": address=reciever addressrole="reciever" dbExecute("insert into addressesintxs (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,balanceavailablecreditdebit) " - "values(%s,%s,%s,%s,%s,%s,%s,%s)", (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,amount)) + "values(%s,%s,%s,%s,%s,%s,%s,%s)", (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,recvamount)) #update pending balance - dbExecute("update addressbalances set balancepending=balancepending+%s where address=%s and propertyid=%s and protocol=%s", (amount,address,protocol)) + dbExecute("update addressbalances set balancepending=balancepending+%s where address=%s and propertyid=%s and protocol=%s", (recvamount,address,protocol)) From c0a2931be7ec3b334f001f0a12f9e205e9483f76 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 9 Jan 2015 13:26:07 -0600 Subject: [PATCH 05/41] Pending tx cleanup --- Gruntfile.js | 20 ++++++------ api/pending.py | 88 ++++++++++++++++++++++++++------------------------ 2 files changed, 56 insertions(+), 52 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 124bc7529..b6c248e0c 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -23,13 +23,13 @@ module.exports = function(grunt) { directory: 'www/bower_components/bitcoinjs-lib' } }, - "crypto-js": { + "crypto-js": { options: { repository: "https://github.com/scintill/crypto-js.git", branch: 'master', directory: 'www/bower_components/bitcoinjs-lib/src/crypto-js' } - } + } }, shell: { html: { @@ -59,14 +59,14 @@ module.exports = function(grunt) { }, command: 'npm install ; npm run minify' }, - "omni-websocket": { - options: { - execOptions: { - cwd: "api/websocket" - } - }, - command: 'npm install' - }, + "omni-websocket": { + options: { + execOptions: { + cwd: "api/websocket" + } + }, + command: 'npm install' + }, cryptolib: { options: { stdout: true, diff --git a/api/pending.py b/api/pending.py index 2731439a2..61fc77276 100644 --- a/api/pending.py +++ b/api/pending.py @@ -4,53 +4,57 @@ def insertpending(txhex): rawtx = decode(txhex) - if 'Amount' not in rawtx['MP'] and rawtx['MP']['Amount']<=0: + if 'Amount' not in rawtx['MP'] or rawtx['MP']['Amount']<=0: #only run if we have a non zero positive amount to process, otherwise exit return - sender = rawtx['Sender'] - reciever = rawtx['Reciever'] - propertyid = rawtx['MP']['PropertyID'] - txtype = rawtx['MP']['TxType'] - txversion = rawtx['MP']['TxVersion'] - txhash = rawtx['BTC']['txid'] - protocol = "Mastercoin" - addresstxindex=0 - txdbserialnum = dbSelect("select least(-1,min(txdbserialnum)) from transactions;") - txdbserialnum -= 1 - amount = rawtx['MP']['Amount'] - - if txtype == 55: - #handle grants to ourself or others - if reciever == "": - sendamount=amount - recvamount=0 + try: + sender = rawtx['Sender'] + receiver = rawtx['Receiver'] + propertyid = rawtx['MP']['PropertyID'] + txtype = rawtx['MP']['TxType'] + txversion = rawtx['MP']['TxVersion'] + txhash = rawtx['BTC']['txid'] + protocol = "Mastercoin" + addresstxindex=0 + txdbserialnum = dbSelect("select least(-1,min(txdbserialnum)) from transactions;") + txdbserialnum -= 1 + amount = rawtx['MP']['Amount'] + + if txtype == 55: + #handle grants to ourself or others + if receiver == "": + sendamount=amount + recvamount=0 + else: + sendamount=0 + recvamount=amount else: - sendamount=0 - recvamount=amount - else: - #all other txs deduct from our balance and, where applicable, apply to the reciever - sendamount=-amount - recvamount=amount - - dbExecute("insert into transactions (txhash,protocol,txdbserialnum,txtype,txversion) values(%s,%s,%s,%s,%s)", - (txhash,protocol,txdbserialnum,txtype,txversion)) + #all other txs deduct from our balance and, where applicable, apply to the reciever + sendamount=-amount + recvamount=amount + + dbExecute("insert into transactions (txhash,protocol,txdbserialnum,txtype,txversion) values(%s,%s,%s,%s,%s)", + (txhash,protocol,txdbserialnum,txtype,txversion)) - address=sender - addressrole="sender" - #insert the addressesintxs entry for the sender - dbExecute("insert into addressesintxs (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,balanceavailablecreditdebit) " - "values(%s,%s,%s,%s,%s,%s,%s,%s)", (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,sendamount)) - - #update pending balance - dbExecute("update addressbalances set balancepending=balancepending-%s where address=%s and propertyid=%s and protocol=%s", (sendamount,address,protocol)) - - if reciever != "": - address=reciever - addressrole="reciever" + address=sender + addressrole="sender" + #insert the addressesintxs entry for the sender dbExecute("insert into addressesintxs (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,balanceavailablecreditdebit) " - "values(%s,%s,%s,%s,%s,%s,%s,%s)", (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,recvamount)) - #update pending balance - dbExecute("update addressbalances set balancepending=balancepending+%s where address=%s and propertyid=%s and protocol=%s", (recvamount,address,protocol)) + "values(%s,%s,%s,%s,%s,%s,%s,%s)", (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,sendamount)) + #update pending balance + dbExecute("update addressbalances set balancepending=balancepending+%s where address=%s and propertyid=%s and protocol=%s", (sendamount,address,protocol)) + + if receiver != "": + address=receiver + addressrole="receiver" + dbExecute("insert into addressesintxs (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,balanceavailablecreditdebit) " + "values(%s,%s,%s,%s,%s,%s,%s,%s)", (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,recvamount)) + #update pending balance + dbExecute("update addressbalances set balancepending=balancepending+%s where address=%s and propertyid=%s and protocol=%s", (recvamount,address,protocol)) + dbCommit() + except Exception,e: + print "Error adding pendingtx: ", txhex + dbRollback() From d202dd6d4de982d89125bc44485d1de744935bcc Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 9 Jan 2015 13:28:54 -0600 Subject: [PATCH 06/41] PendingTx: update db syntax --- api/pending.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pending.py b/api/pending.py index 61fc77276..031127138 100644 --- a/api/pending.py +++ b/api/pending.py @@ -44,7 +44,7 @@ def insertpending(txhex): "values(%s,%s,%s,%s,%s,%s,%s,%s)", (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,sendamount)) #update pending balance - dbExecute("update addressbalances set balancepending=balancepending+%s where address=%s and propertyid=%s and protocol=%s", (sendamount,address,protocol)) + dbExecute("update addressbalances set balancepending=balancepending+%s::numeric where address=%s and propertyid=%s and protocol=%s", (sendamount,address,protocol)) if receiver != "": address=receiver @@ -52,7 +52,7 @@ def insertpending(txhex): dbExecute("insert into addressesintxs (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,balanceavailablecreditdebit) " "values(%s,%s,%s,%s,%s,%s,%s,%s)", (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,recvamount)) #update pending balance - dbExecute("update addressbalances set balancepending=balancepending+%s where address=%s and propertyid=%s and protocol=%s", (recvamount,address,protocol)) + dbExecute("update addressbalances set balancepending=balancepending+%s::numeric where address=%s and propertyid=%s and protocol=%s", (recvamount,address,protocol)) dbCommit() except Exception,e: print "Error adding pendingtx: ", txhex From d236ad8963dde6bd9074ca2d9086eb11e3a6a886 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 9 Jan 2015 14:34:44 -0600 Subject: [PATCH 07/41] add testnet support to decoder --- api/decode.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/api/decode.py b/api/decode.py index 65c1a24a9..2f90651ad 100644 --- a/api/decode.py +++ b/api/decode.py @@ -38,8 +38,16 @@ def decode(rawhex): #filter keys that are ref nonrefkeys = [] + + #check for testnet addresses + if reference[:1] in ['2','m','n']: + #testnet address + offset=111 + else: + offset=0 + for compressedkey in scriptkeys: - if pybitcointools.pubtoaddr(compressedkey) not in senders : + if pybitcointools.pubtoaddr(compressedkey,offset) not in senders : nonrefkeys.append(compressedkey) max_seqnum = len(nonrefkeys) From e8976e3d8c3dd301d7a291b32e473e72349482e2 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 9 Jan 2015 14:46:23 -0600 Subject: [PATCH 08/41] Update: Check push response --- api/pushtx.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pushtx.py b/api/pushtx.py index 30cd164c3..dd50e09e9 100644 --- a/api/pushtx.py +++ b/api/pushtx.py @@ -43,7 +43,7 @@ def pushtx_response(response_dict): response=pushtxnode(signed_tx) - if "NOTOK" not in response['status']: + if "NOTOK" not in response: insertpending(signed_tx) print signed_tx,'\n', response From c58936488a8ff8ca1ba8d29a5e7bda2bfde89b4d Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 9 Jan 2015 14:52:06 -0600 Subject: [PATCH 09/41] Decode: abstract api from native call --- api/decode.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/api/decode.py b/api/decode.py index 2f90651ad..80aa64b18 100644 --- a/api/decode.py +++ b/api/decode.py @@ -8,6 +8,10 @@ app.debug = True @app.route('/') +def decode_handler(rawhex): + return jsonify(decode(rawhex)) + + def decode(rawhex): transaction = decoderawtransaction(rawhex)['result'] @@ -187,5 +191,5 @@ def decode(rawhex): } print retval - return jsonify({'Sender':reference,'Receiver':dest,'MP':retval,'BTC':transaction}) + return {'Sender':reference,'Receiver':dest,'MP':retval,'BTC':transaction} From 39caa42d4a62ef9af57acac5f1cce8c8560bf34e Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 9 Jan 2015 14:55:44 -0600 Subject: [PATCH 10/41] PendingTx: print errors --- api/pending.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pending.py b/api/pending.py index 031127138..b7650588c 100644 --- a/api/pending.py +++ b/api/pending.py @@ -55,6 +55,6 @@ def insertpending(txhex): dbExecute("update addressbalances set balancepending=balancepending+%s::numeric where address=%s and propertyid=%s and protocol=%s", (recvamount,address,protocol)) dbCommit() except Exception,e: - print "Error adding pendingtx: ", txhex + print "Error: ", e "\n Could not add PendingTx: ", txhex dbRollback() From d42a7a321bceee5532f55d77c8ec407f5cad4faf Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 9 Jan 2015 15:23:10 -0600 Subject: [PATCH 11/41] PendingTx: Fix sql syntax --- api/pending.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/api/pending.py b/api/pending.py index b7650588c..cef77c3d1 100644 --- a/api/pending.py +++ b/api/pending.py @@ -17,7 +17,7 @@ def insertpending(txhex): txhash = rawtx['BTC']['txid'] protocol = "Mastercoin" addresstxindex=0 - txdbserialnum = dbSelect("select least(-1,min(txdbserialnum)) from transactions;") + txdbserialnum = dbSelect("select least(-1,min(txdbserialnum)) from transactions;")[0][0] txdbserialnum -= 1 amount = rawtx['MP']['Amount'] @@ -41,20 +41,20 @@ def insertpending(txhex): addressrole="sender" #insert the addressesintxs entry for the sender dbExecute("insert into addressesintxs (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,balanceavailablecreditdebit) " - "values(%s,%s,%s,%s,%s,%s,%s,%s)", (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,sendamount)) + "values(%s,%s,%s,%s,%s,%s,%s)", (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,sendamount)) #update pending balance - dbExecute("update addressbalances set balancepending=balancepending+%s::numeric where address=%s and propertyid=%s and protocol=%s", (sendamount,address,protocol)) + 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 - addressrole="receiver" + addressrole="recipient" dbExecute("insert into addressesintxs (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,balanceavailablecreditdebit) " - "values(%s,%s,%s,%s,%s,%s,%s,%s)", (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,recvamount)) + "values(%s,%s,%s,%s,%s,%s,%s)", (address,propertyid,protocol,txdbserialnum,addresstxindex,addressrole,recvamount)) #update pending balance - dbExecute("update addressbalances set balancepending=balancepending+%s::numeric where address=%s and propertyid=%s and protocol=%s", (recvamount,address,protocol)) + dbExecute("update addressbalances set balancepending=balancepending+%s::numeric where address=%s and propertyid=%s and protocol=%s", (recvamount,address,propertyid,protocol)) dbCommit() except Exception,e: - print "Error: ", e "\n Could not add PendingTx: ", txhex + print "Error: ", e, "\n Could not add PendingTx: ", txhex dbRollback() From 8f2dad8594836d5af150f4ef9c178c92320b84be Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 9 Jan 2015 16:28:24 -0600 Subject: [PATCH 12/41] Add pending balance to websocket balance return --- api/websocket.py | 1 + 1 file changed, 1 insertion(+) diff --git a/api/websocket.py b/api/websocket.py index b4a9f56e2..c5c7c58d2 100644 --- a/api/websocket.py +++ b/api/websocket.py @@ -36,6 +36,7 @@ def get_balancedata(address): divi = balrow[-1]['divisible'] if type(balrow[-1]) == type({}) else json.loads(balrow[-1])['divisible'] #Divisibility res = { 'symbol' : sym_t, 'divisible' : divi, 'id' : cID } res['value'] = ('%.8f' % float(balrow[4])).rstrip('0').rstrip('.') + res['pending_balance'] = ('%.8f' % float(balrow[8])).rstrip('0').rstrip('.') #res['reserved_balance'] = ('%.8f' % float(balrow[5])).rstrip('0').rstrip('.') balance_data['balance'].append(res) From c2ba1e69777fdc463aaf0a11fd0ccab46592638f Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 9 Jan 2015 16:49:17 -0600 Subject: [PATCH 13/41] Add btc pending balance --- api/websocket.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/api/websocket.py b/api/websocket.py index c5c7c58d2..c10102bf5 100644 --- a/api/websocket.py +++ b/api/websocket.py @@ -36,7 +36,7 @@ def get_balancedata(address): divi = balrow[-1]['divisible'] if type(balrow[-1]) == type({}) else json.loads(balrow[-1])['divisible'] #Divisibility res = { 'symbol' : sym_t, 'divisible' : divi, 'id' : cID } res['value'] = ('%.8f' % float(balrow[4])).rstrip('0').rstrip('.') - res['pending_balance'] = ('%.8f' % float(balrow[8])).rstrip('0').rstrip('.') + res['pending'] = ('%.8f' % float(balrow[8])).rstrip('0').rstrip('.') #res['reserved_balance'] = ('%.8f' % float(balrow[5])).rstrip('0').rstrip('.') balance_data['balance'].append(res) @@ -46,12 +46,15 @@ def get_balancedata(address): btc_balance = { 'symbol': 'BTC', 'divisible': True, 'id' : 0 } out, err = run_command(TIMEOUT+ 'sx balance -j ' + addr ) if err != None or out == '': - btc_balance[ 'value' ] = int(-666) + btc_balance[ 'value' ] = int(-555) + btc_balance['pending'] = int(0) else: try: btc_balance[ 'value' ] = int( json.loads( out )[0][ 'paid' ]) + btc_balance['pending'] = int( json.loads( out )[0][ 'pending' ] - json.loads( out )[0][ 'paid' ]) except ValueError: - btc_balance[ 'value' ] = int(-666) + btc_balance[ 'value' ] = int(-555) + btc_balance['pending'] = int(0) balance_data['balance'].append(btc_balance) return balance_data From c6d742bb86a5d9d405378b0583dac9310ac3c34d Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 9 Jan 2015 16:52:32 -0600 Subject: [PATCH 14/41] Fix unicode math error --- api/websocket.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/websocket.py b/api/websocket.py index c10102bf5..2bd620cfb 100644 --- a/api/websocket.py +++ b/api/websocket.py @@ -51,7 +51,7 @@ def get_balancedata(address): else: try: btc_balance[ 'value' ] = int( json.loads( out )[0][ 'paid' ]) - btc_balance['pending'] = int( json.loads( out )[0][ 'pending' ] - json.loads( out )[0][ 'paid' ]) + btc_balance['pending'] = int( json.loads( out )[0][ 'pending' ] ) - int( json.loads( out )[0][ 'paid' ]) except ValueError: btc_balance[ 'value' ] = int(-555) btc_balance['pending'] = int(0) From bc08d9e883df50b139218729810823e8b8d530cb Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 9 Jan 2015 17:32:25 -0600 Subject: [PATCH 15/41] display pending balance --- www/js/controller.js | 8 ++++++-- www/partials/wallet_address_list.html | 3 +++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/www/js/controller.js b/www/js/controller.js index 794425f41..486236fff 100644 --- a/www/js/controller.js +++ b/www/js/controller.js @@ -25,14 +25,18 @@ function HomeCtrl($scope, $templateCache, $injector, $location, $http, $q, Accou var appraiser = $injector.get('appraiser'); $injector.get('balanceService').balance($scope.balanceAddress).then(function(result) { result.data.balance.forEach(function(currencyItem, index, collection) { - if(currencyItem.divisible) + if(currencyItem.divisible) { var value=new Big(currencyItem.value).times(WHOLE_UNIT).valueOf(); - + var pending=value+ new Big(currencyItem.pending).times(WHOLE_UNIT).valueOf(); + } else { + var pending=currencyItem.value+currencyItem.pending; + } appraiser.updateValue(function() { balances[currencyItem.symbol] = { "symbol": currencyItem.symbol, "balance": +value || currencyItem.value, "value": appraiser.getValue(currencyItem.value, currencyItem.symbol, currencyItem.divisible), + "pending": pending, }; if (currencyItem.symbol == 'BTC') { balances[currencyItem.symbol].name = "Bitcoin"; diff --git a/www/partials/wallet_address_list.html b/www/partials/wallet_address_list.html index 249c2f812..236ccda07 100644 --- a/www/partials/wallet_address_list.html +++ b/www/partials/wallet_address_list.html @@ -46,6 +46,9 @@

Invalid Addresses in Your Wallet

{{currency.symbol}} + + + ()