Skip to content
This repository was archived by the owner on May 16, 2019. It is now read-only.

Commit ddf06d3

Browse files
authored
Merge pull request #428 from cpacia/master
Sort outpoints when releasing funds from moderator
2 parents c1efe32 + ac37ea0 commit ddf06d3

File tree

9 files changed

+95
-15
lines changed

9 files changed

+95
-15
lines changed

api/restapi.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,7 +1119,8 @@ def get_sales(self, request):
11191119
"thumbnail_hash": sale[6],
11201120
"buyer": sale[7],
11211121
"contract_type": sale[8],
1122-
"unread": sale[9]
1122+
"unread": sale[9],
1123+
"status_changed": False if sale[10] == 0 else True
11231124
}
11241125
sales_list.append(sale_json)
11251126
request.setHeader('content-type', "application/json")
@@ -1143,7 +1144,8 @@ def get_purchases(self, request):
11431144
"thumbnail_hash": purchase[6],
11441145
"vendor": purchase[7],
11451146
"contract_type": purchase[8],
1146-
"unread": purchase[9]
1147+
"unread": purchase[9],
1148+
"status_changed": False if purchase[10] == 0 else True
11471149
}
11481150
purchases_list.append(purchase_json)
11491151
request.setHeader('content-type', "application/json")
@@ -1181,23 +1183,30 @@ def get_order(self, request):
11811183
if os.path.exists(os.path.join(DATA_FOLDER, "purchases", "unfunded", filename)):
11821184
file_path = os.path.join(DATA_FOLDER, "purchases", "unfunded", filename)
11831185
status = self.db.purchases.get_status(request.args["order_id"][0])
1186+
self.db.purchases.status_changed(request.args["order_id"][0], 0)
11841187
elif os.path.exists(os.path.join(DATA_FOLDER, "purchases", "in progress", filename)):
11851188
file_path = os.path.join(DATA_FOLDER, "purchases", "in progress", filename)
11861189
status = self.db.purchases.get_status(request.args["order_id"][0])
1190+
self.db.purchases.status_changed(request.args["order_id"][0], 0)
11871191
elif os.path.exists(os.path.join(DATA_FOLDER, "purchases", "trade receipts", filename)):
11881192
file_path = os.path.join(DATA_FOLDER, "purchases", "trade receipts", filename)
11891193
status = self.db.purchases.get_status(request.args["order_id"][0])
1194+
self.db.purchases.status_changed(request.args["order_id"][0], 0)
11901195
elif os.path.exists(os.path.join(DATA_FOLDER, "store", "contracts", "unfunded", filename)):
11911196
file_path = os.path.join(DATA_FOLDER, "store", "contracts", "unfunded", filename)
11921197
status = self.db.sales.get_status(request.args["order_id"][0])
1198+
self.db.sales.status_changed(request.args["order_id"][0], 0)
11931199
elif os.path.exists(os.path.join(DATA_FOLDER, "store", "contracts", "in progress", filename)):
11941200
file_path = os.path.join(DATA_FOLDER, "store", "contracts", "in progress", filename)
11951201
status = self.db.sales.get_status(request.args["order_id"][0])
1202+
self.db.sales.status_changed(request.args["order_id"][0], 0)
11961203
elif os.path.exists(os.path.join(DATA_FOLDER, "store", "contracts", "trade receipts", filename)):
11971204
file_path = os.path.join(DATA_FOLDER, "store", "contracts", "trade receipts", filename)
11981205
status = self.db.sales.get_status(request.args["order_id"][0])
1206+
self.db.sales.status_changed(request.args["order_id"][0], 0)
11991207
elif os.path.exists(os.path.join(DATA_FOLDER, "cases", filename)):
12001208
file_path = os.path.join(DATA_FOLDER, "cases", filename)
1209+
self.db.cases.status_changed(request.args["order_id"][0], 0)
12011210
status = 4
12021211
else:
12031212
request.write(json.dumps({}, indent=4))
@@ -1325,7 +1334,8 @@ def get_cases(self, request):
13251334
"vendor": case[7],
13261335
"validation": json.loads(case[8]),
13271336
"status": "closed" if case[10] == 1 else "open",
1328-
"unread": case[11]
1337+
"unread": case[11],
1338+
"status_changed": False if case[12] == 0 else True
13291339
}
13301340
cases_list.append(purchase_json)
13311341
request.setHeader('content-type', "application/json")

db/datastore.py

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from protos import objects
1111
from protos.objects import Listings, Followers, Following
1212
from os.path import join
13-
from db.migrations import migration1, migration2, migration3, migration4, migration5
13+
from db.migrations import migration1, migration2, migration3, migration4, migration5, migration6
1414

1515

1616
class Database(object):
@@ -116,7 +116,7 @@ def _create_database(database_path):
116116
conn = lite.connect(database_path)
117117
cursor = conn.cursor()
118118

119-
cursor.execute('''PRAGMA user_version = 5''')
119+
cursor.execute('''PRAGMA user_version = 6''')
120120
cursor.execute('''CREATE TABLE hashmap(hash TEXT PRIMARY KEY, filepath TEXT)''')
121121

122122
cursor.execute('''CREATE TABLE profile(id INTEGER PRIMARY KEY, serializedUserInfo BLOB, tempHandle TEXT)''')
@@ -152,15 +152,15 @@ def _create_database(database_path):
152152

153153
cursor.execute('''CREATE TABLE purchases(id TEXT PRIMARY KEY, title TEXT, description TEXT,
154154
timestamp INTEGER, btc FLOAT, address TEXT, status INTEGER, outpoint BLOB, thumbnail BLOB, vendor TEXT,
155-
proofSig BLOB, contractType TEXT, unread INTEGER)''')
155+
proofSig BLOB, contractType TEXT, unread INTEGER, statusChanged INTEGER)''')
156156

157157
cursor.execute('''CREATE TABLE sales(id TEXT PRIMARY KEY, title TEXT, description TEXT,
158158
timestamp INTEGER, btc REAL, address TEXT, status INTEGER, thumbnail BLOB, outpoint BLOB, buyer TEXT,
159-
paymentTX TEXT, contractType TEXT, unread INTEGER)''')
159+
paymentTX TEXT, contractType TEXT, unread INTEGER, statusChanged INTEGER)''')
160160

161161
cursor.execute('''CREATE TABLE cases(id TEXT PRIMARY KEY, title TEXT, timestamp INTEGER, orderDate TEXT,
162162
btc REAL, thumbnail BLOB, buyer TEXT, vendor TEXT, validation TEXT, claim TEXT, status INTEGER,
163-
unread INTEGER)''')
163+
unread INTEGER, statusChanged INTEGER)''')
164164

165165
cursor.execute('''CREATE TABLE ratings(listing TEXT, ratingID TEXT, rating TEXT)''')
166166
cursor.execute('''CREATE INDEX index_listing ON ratings(listing);''')
@@ -204,6 +204,9 @@ def _run_migrations(self):
204204
migration5.migrate(self.PATH)
205205
elif version == 4:
206206
migration5.migrate(self.PATH)
207+
migration6.migrate(self.PATH)
208+
elif version == 5:
209+
migration6.migrate(self.PATH)
207210

208211

209212
class HashMap(object):
@@ -927,7 +930,7 @@ def get_all(self):
927930
conn = Database.connect_database(self.PATH)
928931
cursor = conn.cursor()
929932
cursor.execute('''SELECT id, title, description, timestamp, btc, status,
930-
thumbnail, vendor, contractType, unread FROM purchases ''')
933+
thumbnail, vendor, contractType, unread, statusChanged FROM purchases ''')
931934
ret = cursor.fetchall()
932935
conn.close()
933936
return ret
@@ -948,6 +951,14 @@ def update_status(self, order_id, status):
948951
conn.commit()
949952
conn.close()
950953

954+
def status_changed(self, order_id, status):
955+
conn = Database.connect_database(self.PATH)
956+
with conn:
957+
cursor = conn.cursor()
958+
cursor.execute('''UPDATE purchases SET statusChanged=? WHERE id=?;''', (status, order_id))
959+
conn.commit()
960+
conn.close()
961+
951962
def get_status(self, order_id):
952963
conn = Database.connect_database(self.PATH)
953964
cursor = conn.cursor()
@@ -1048,7 +1059,7 @@ def get_all(self):
10481059
conn = Database.connect_database(self.PATH)
10491060
cursor = conn.cursor()
10501061
cursor.execute('''SELECT id, title, description, timestamp, btc, status,
1051-
thumbnail, buyer, contractType, unread FROM sales ''')
1062+
thumbnail, buyer, contractType, unread, statusChanged FROM sales ''')
10521063
ret = cursor.fetchall()
10531064
conn.close()
10541065
return ret
@@ -1069,6 +1080,14 @@ def update_status(self, order_id, status):
10691080
conn.commit()
10701081
conn.close()
10711082

1083+
def status_changed(self, order_id, status):
1084+
conn = Database.connect_database(self.PATH)
1085+
with conn:
1086+
cursor = conn.cursor()
1087+
cursor.execute('''UPDATE sales SET statusChanged=? WHERE id=?;''', (status, order_id))
1088+
conn.commit()
1089+
conn.close()
1090+
10721091
def get_status(self, order_id):
10731092
conn = Database.connect_database(self.PATH)
10741093
cursor = conn.cursor()
@@ -1154,7 +1173,7 @@ def get_all(self):
11541173
conn = Database.connect_database(self.PATH)
11551174
cursor = conn.cursor()
11561175
cursor.execute('''SELECT id, title, timestamp, orderDate, btc, thumbnail,
1157-
buyer, vendor, validation, claim, status, unread FROM cases ''')
1176+
buyer, vendor, validation, claim, status, unread, statusChanged FROM cases ''')
11581177
ret = cursor.fetchall()
11591178
conn.close()
11601179
return ret
@@ -1189,6 +1208,14 @@ def update_status(self, order_id, status):
11891208
conn.commit()
11901209
conn.close()
11911210

1211+
def status_changed(self, order_id, status):
1212+
conn = Database.connect_database(self.PATH)
1213+
with conn:
1214+
cursor = conn.cursor()
1215+
cursor.execute('''UPDATE cases SET statusChanged=? WHERE id=?;''', (status, order_id))
1216+
conn.commit()
1217+
conn.close()
1218+
11921219

11931220
class Ratings(object):
11941221
"""

db/migrations/migration5.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import sqlite3
22

3-
43
def migrate(database_path):
54
print "migrating to db version 5"
65
conn = sqlite3.connect(database_path)

db/migrations/migration6.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import sqlite3
2+
3+
4+
def migrate(database_path):
5+
print "migrating to db version 6"
6+
conn = sqlite3.connect(database_path)
7+
conn.text_factory = str
8+
cursor = conn.cursor()
9+
10+
cursor.execute('''ALTER TABLE sales ADD COLUMN "statusChanged" INTEGER''')
11+
cursor.execute('''ALTER TABLE purchases ADD COLUMN "statusChanged" INTEGER''')
12+
cursor.execute('''ALTER TABLE cases ADD COLUMN "statusChanged" INTEGER''')
13+
14+
cursor.execute('''UPDATE purchases SET statusChanged = 0;''')
15+
cursor.execute('''UPDATE purchases SET statusChanged = 0;''')
16+
cursor.execute('''UPDATE purchases SET statusChanged = 0;''')
17+
18+
# update version
19+
cursor.execute('''PRAGMA user_version = 6''')
20+
conn.commit()
21+
conn.close()

market/contracts.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@ def accept_order_confirmation(self, notification_listener, confirmation_json=Non
515515

516516
# update the order status in the db
517517
self.db.purchases.update_status(contract_hash, 2)
518+
self.db.purchases.status_changed(contract_hash, 1)
518519
file_path = os.path.join(DATA_FOLDER, "purchases", "in progress", contract_hash + ".json")
519520

520521
# update the contract in the file system
@@ -769,6 +770,7 @@ def accept_receipt(self, notification_listener, blockchain, receipt_json=None):
769770
json.dumps(self.contract["buyer_receipt"]["receipt"]["rating"], indent=4))
770771

771772
if status == 2:
773+
self.db.sales.status_changed(order_id, 1)
772774
self.db.sales.update_status(order_id, 3)
773775
file_path = os.path.join(DATA_FOLDER, "store", "contracts", "trade receipts", order_id + ".json")
774776
with open(file_path, 'w') as outfile:
@@ -933,6 +935,7 @@ def payment_received(self):
933935
% order_id)
934936

935937
self.db.sales.update_status(order_id, 1)
938+
self.db.sales.status_changed(order_id, 1)
936939
self.db.sales.update_outpoint(order_id, json.dumps(self.outpoints))
937940
self.log.info("Received new order %s" % order_id)
938941

@@ -1103,6 +1106,7 @@ def process_refund(self, refund_json, blockchain, notification_listener):
11031106
self.log.info("broadcasting refund tx %s to network" % tx.get_hash())
11041107

11051108
self.db.purchases.update_status(order_id, 7)
1109+
self.db.purchases.status_changed(order_id, 1)
11061110
file_path = os.path.join(DATA_FOLDER, "purchases", "trade receipts", order_id + ".json")
11071111
with open(file_path, 'w') as outfile:
11081112
outfile.write(json.dumps(self.contract, indent=4))

market/moderation.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,11 @@ def process_dispute(contract, db, message_listener, notification_listener, testn
7878
p.avatar_hash = unhexlify(str(contract["dispute"]["info"]["avatar_hash"]))
7979

8080
if db.purchases.get_purchase(order_id) is not None:
81+
db.purchases.status_changed(order_id, 1)
8182
db.purchases.update_status(order_id, 4)
8283

8384
elif db.sales.get_sale(order_id) is not None:
85+
db.sales.status_changed(order_id, 1)
8486
db.sales.update_status(order_id, 4)
8587

8688
elif "moderators" in contract["vendor_offer"]["listing"]:
@@ -175,9 +177,11 @@ def close_dispute(resolution_json, db, message_listener, notification_listener,
175177
contract["dispute_resolution"] = resolution_json["dispute_resolution"]
176178

177179
if db.purchases.get_purchase(order_id) is not None:
180+
db.purchases.status_changed(order_id, 1)
178181
db.purchases.update_status(order_id, 5)
179182

180183
elif db.sales.get_sale(order_id) is not None:
184+
db.sales.status_changed(order_id, 1)
181185
db.sales.update_status(order_id, 5)
182186

183187
with open(file_path, 'wb') as outfile:

market/network.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
import os.path
1414
import pickle
1515
import time
16+
import struct
1617
from binascii import unhexlify
18+
from bitcoin.core import b2lx
1719
from collections import OrderedDict
1820
from config import DATA_FOLDER, TRANSACTION_FEE
1921
from dht.node import Node
@@ -953,6 +955,7 @@ def release_funds(self, order_id):
953955
This function should be called to release funds from a disputed contract after
954956
the moderator has resolved the dispute and provided his signature.
955957
"""
958+
956959
if os.path.exists(os.path.join(DATA_FOLDER, "purchases", "in progress", order_id + ".json")):
957960
file_path = os.path.join(DATA_FOLDER, "purchases", "in progress", order_id + ".json")
958961
outpoints = json.loads(self.db.purchases.get_outpoint(order_id))
@@ -983,6 +986,16 @@ def release_funds(self, order_id):
983986
["resolution"]["vendor_payout"]) * 100000000)),
984987
'address': vendor_address})
985988

989+
# version 0.2.1 and above ensure same sort order as moderator.
990+
o = []
991+
for s in contract["dispute_resolution"]["resolution"]["tx_signatures"]:
992+
if "outpoint" in s:
993+
for outpoint in outpoints:
994+
ser = outpoint["txid"] + b2lx(struct.pack(b"<I", outpoint["vout"]))
995+
if ser == s["outpoint"]:
996+
o.append(outpoint)
997+
if len(o) != 0:
998+
outpoints = o
986999
tx = BitcoinTransaction.make_unsigned(outpoints, outputs, testnet=self.protocol.multiplexer.testnet)
9871000
chaincode = contract["buyer_order"]["order"]["payment"]["chaincode"]
9881001
redeem_script = str(contract["buyer_order"]["order"]["payment"]["redeem_script"])

market/transactions.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ def create_signature(self, privkey, reedem_script):
9797
sighash = SignatureHash(CScript(x(reedem_script)), self.tx, i, SIGHASH_ALL)
9898
signatures.append({
9999
"index": i,
100-
"signature": (seckey.sign(sighash) + struct.pack('<B', SIGHASH_ALL)).encode("hex")
100+
"signature": (seckey.sign(sighash) + struct.pack('<B', SIGHASH_ALL)).encode("hex"),
101+
"outpoint": b2lx(self.tx.vin[i].prevout.hash) + b2lx(struct.pack(b"<I", self.tx.vin[i].prevout.n))
101102
})
102103
return signatures
103104

openbazaard.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
from twisted.python import log, logfile
3838
from txws import WebSocketFactory
3939

40+
4041
def run(*args):
4142
TESTNET = args[0]
4243
LOGLEVEL = args[1]
@@ -213,7 +214,7 @@ class Parser(object):
213214
def __init__(self, daemon):
214215
self.daemon = daemon
215216
parser = argparse.ArgumentParser(
216-
description='OpenBazaar-Server v0.2.0',
217+
description='OpenBazaar-Server v0.2.1',
217218
usage='''
218219
python openbazaard.py <command> [<args>]
219220
python openbazaard.py <command> --help
@@ -302,6 +303,6 @@ def print_splash_screen():
302303
print "\_______ / __/ \___ >___| /" + OKBLUE + "______ /(____ /_____ \(____ (____ /__|" + ENDC
303304
print " \/|__| \/ \/ " + OKBLUE + " \/ \/ \/ \/ \/" + ENDC
304305
print
305-
print "OpenBazaar Server v0.1 starting..."
306+
print "OpenBazaar Server v0.2.1 starting..."
306307

307308
Parser(OpenBazaard('/tmp/openbazaard.pid'))

0 commit comments

Comments
 (0)