Browse Source

adapt merchant script to SPV

master
thomasv 13 years ago
parent
commit
386c8d9ee6
  1. 111
      scripts/merchant.py

111
scripts/merchant.py

@ -21,7 +21,7 @@ import time, thread, sys, socket, os
import urllib2,json import urllib2,json
import MySQLdb as mdb import MySQLdb as mdb
import Queue import Queue
from electrum import Wallet, Interface, WalletVerifier from electrum import Wallet, Interface, WalletVerifier, SimpleConfig, WalletSynchronizer
import ConfigParser import ConfigParser
config = ConfigParser.ConfigParser() config = ConfigParser.ConfigParser()
@ -42,61 +42,58 @@ cb_received = config.get('callback','received')
cb_expired = config.get('callback','expired') cb_expired = config.get('callback','expired')
cb_password = config.get('callback','password') cb_password = config.get('callback','password')
wallet = Wallet()
wallet.master_public_key = config.get('electrum','mpk')
wallet_config = SimpleConfig()
master_public_key = config.get('electrum','mpk')
wallet_config.set_key('master_public_key',master_public_key)
wallet = Wallet(wallet_config)
wallet.synchronize = lambda: None # prevent address creation by the wallet
omg_addresses = {} omg_addresses = {}
def electrum_input_thread(in_queue): def input_reader_thread(request_queue):
while True: while True:
addr, amount, confirmations = in_queue.get(True,1000000000) addr, amount, confirmations = request_queue.get(True,1000000000)
if addr in omg_addresses: if addr in omg_addresses:
continue continue
else: else:
print "subscribing to ", addr print "subscribing to ", addr
omg_addresses[addr] = {'requested':float(amount), 'confirmations':int(confirmations)} omg_addresses[addr] = {'requested':float(amount), 'confirmations':int(confirmations)}
interface.send([('blockchain.address.subscribe',[addr])])
if addr not in wallet.addresses:
with wallet.lock:
print "adding %s to wallet"%addr
wallet.addresses.append(addr)
wallet.history[addr] = []
synchronizer.subscribe_to_addresses([addr])
wallet.up_to_date = False
def electrum_output_thread(out_queue):
while True:
r = interface.get_response() def on_wallet_update():
print r print "updated_callback"
method = r.get('method') for addr in omg_addresses:
h = wallet.history.get(addr)
if method == 'blockchain.address.subscribe':
addr = r.get('params')[0] requested_amount = omg_addresses[addr].get('requested')
interface.send([('blockchain.address.get_history',[addr])]) requested_confs = omg_addresses[addr].get('confirmations')
elif method == 'blockchain.address.get_history': value = 0
addr = r.get('params')[0] for tx_hash, tx_height in h:
h = r.get('result')
if h is None: continue tx = wallet.transactions.get(tx_hash)
omg_addresses[addr]['history'] = h if not tx: continue
for item in h: if verifier.get_confirmations(tx_hash) < requested_confs: continue
tx_hash = item.get('tx_hash') for o in tx.get('outputs'):
verifier.add(tx_hash) if o.get('address') == addr:
value += o.get('value')
elif method == 'blockchain.numblocks.subscribe':
for addr in omg_addresses: s = (value)/1.e8
h = omg_addresses[addr].get('history',[]) print "balance for %s:"%addr, s, requested_amount
amount = omg_addresses[addr].get('requested') if s>= requested_amount:
confs = omg_addresses[addr].get('confirmations') print "payment accepted", addr
val = 0 out_queue.put( ('payment', addr))
for item in h:
tx_hash = item.get('tx_hash')
v = item['value']
if v<0: continue
if verifier.get_confirmations(tx_hash) >= conf:
val += v
s = (val)/1.e8
print "balance for %s:"%addr, s
if s>=amount:
out_queue.put( ('payment',addr) )
stopping = False stopping = False
@ -115,7 +112,7 @@ def process_request(i, amount, confirmations, expires_in, password):
print "process_request", i, amount, confirmations, expires_in print "process_request", i, amount, confirmations, expires_in
if password!=my_password: if password!=my_password:
print "wrong password ", password print "wrong password ", password
return return
addr = wallet.get_new_address(i, 0) addr = wallet.get_new_address(i, 0)
out_queue.put( ('request',(i,addr,amount,expires_in) )) out_queue.put( ('request',(i,addr,amount,expires_in) ))
return addr return addr
@ -168,27 +165,32 @@ if __name__ == '__main__':
interface.start() interface.start()
interface.send([('blockchain.numblocks.subscribe',[])]) interface.send([('blockchain.numblocks.subscribe',[])])
verifier = WalletVerifier(interface, {}) wallet.interface = interface
interface.register_callback('updated', on_wallet_update)
verifier = WalletVerifier(interface, wallet_config)
wallet.set_verifier(verifier)
synchronizer = WalletSynchronizer(wallet, wallet_config)
synchronizer.start()
verifier.start() verifier.start()
# this process detects when addresses have paid # this process detects when addresses have paid
in_queue = Queue.Queue() request_queue = Queue.Queue()
out_queue = Queue.Queue() out_queue = Queue.Queue()
thread.start_new_thread(electrum_input_thread, (in_queue,)) thread.start_new_thread(input_reader_thread, (request_queue,))
thread.start_new_thread(electrum_output_thread, (out_queue,))
thread.start_new_thread(server_thread, (conn,)) thread.start_new_thread(server_thread, (conn,))
while not stopping: while not stopping:
cur = conn.cursor() cur = conn.cursor()
# get a list of addresses to watch # read pending requests from table
cur.execute("SELECT address, amount, confirmations FROM electrum_payments WHERE paid IS NULL;") cur.execute("SELECT address, amount, confirmations FROM electrum_payments WHERE paid IS NULL;")
data = cur.fetchall() data = cur.fetchall()
for item in data: for item in data:
in_queue.put(item) request_queue.put(item)
try: try:
cmd, params = out_queue.get(True, 10) cmd, params = out_queue.get(True, 10)
@ -196,12 +198,15 @@ if __name__ == '__main__':
cmd = '' cmd = ''
if cmd == 'payment': if cmd == 'payment':
addr = params
# set paid=1 for received payments # set paid=1 for received payments
print "received payment from", addr print "received payment from", addr
cur.execute("select id from electrum_payments where address='%s';"%addr) cur.execute("select id from electrum_payments where address='%s';"%addr)
id = cur.fetchone()[0] id = cur.fetchone()[0]
cur.execute("update electrum_payments set paid=1 where id=%d;"%(id)) cur.execute("update electrum_payments set paid=1 where id=%d;"%(id))
elif cmd == 'request': elif cmd == 'request':
# add a new request to the table.
i, addr, amount, confs, hours = params i, addr, amount, confs, hours = params
sql = "INSERT INTO electrum_payments (id, address, amount, confirmations, received_at, expires_at, paid, processed)"\ sql = "INSERT INTO electrum_payments (id, address, amount, confirmations, received_at, expires_at, paid, processed)"\
+ " VALUES (%d, '%s', %f, %d, CURRENT_TIMESTAMP, ADDTIME(CURRENT_TIMESTAMP, '0 %d:0:0'), NULL, NULL);"%(i, addr, amount, confs, hours) + " VALUES (%d, '%s', %f, %d, CURRENT_TIMESTAMP, ADDTIME(CURRENT_TIMESTAMP, '0 %d:0:0'), NULL, NULL);"%(i, addr, amount, confs, hours)
@ -234,5 +239,7 @@ if __name__ == '__main__':
conn.close() conn.close()
print "terminated"

Loading…
Cancel
Save