print_log("ERROR: cannot parse", txid)
return None
+
def get_history(self, addr, cache_only=False):
with self.cache_lock:
hist = self.history_cache.get(addr)
with self.dblock:
try:
- h = self.storage.get_history(str((addr)))
- hist = self.storage.deserialize(h)
+ hist = self.storage.get_history(addr)
is_known = True
except:
self.shared.stop()
hist = []
is_known = False
- # sort history, because redeeming transactions are next to the corresponding txout
- hist.sort(key=lambda tup: tup[2])
-
# add memory pool
with self.mempool_lock:
for txid in self.mempool_hist.get(addr, []):
- hist.append((txid, 0, 0))
-
- # uniqueness
- hist = set(map(lambda x: (x[0], x[2]), hist))
-
- # convert to dict
- hist = map(lambda x: {'tx_hash': x[0], 'height': x[1]}, hist)
+ hist.append({'tx_hash':txid, 'height':0})
# add something to distinguish between unused and empty addresses
if hist == [] and is_known:
self.history_cache[addr] = hist
return hist
+
def get_status(self, addr, cache_only=False):
tx_points = self.get_history(addr, cache_only)
if cache_only and tx_points == -1:
elif method == 'blockchain.address.subscribe':
try:
- address = params[0]
+ address = str(params[0])
result = self.get_status(address, cache_only)
except BaseException, e:
error = str(e) + ': ' + address
elif method == 'blockchain.address.get_history':
try:
- address = params[0]
+ address = str(params[0])
result = self.get_history(address, cache_only)
except BaseException, e:
error = str(e) + ': ' + address
print_log("error:", error)
+ elif method == 'blockchain.address.get_balance':
+ try:
+ address = str(params[0])
+ result = self.storage.get_balance(address)
+ except BaseException, e:
+ error = str(e) + ': ' + address
+ print_log("error:", error)
+
+ elif method == 'blockchain.address.get_path':
+ try:
+ address = str(params[0])
+ result = self.storage.get_address_path(address)
+ except BaseException, e:
+ error = str(e) + ': ' + address
+ print_log("error:", error)
+
+ elif method == 'blockchain.address.listunspent':
+ try:
+ address = str(params[0])
+ result = self.storage.listunspent(address)
+ except BaseException, e:
+ error = str(e) + ': ' + address
+ print_log("error:", error)
+
elif method == 'blockchain.block.get_header':
if cache_only:
result = -1
return hash_160_to_bc_address(addr)
+ def get_address_path(self, addr):
+ key = self.address_to_key(addr)
+ p = self.get_path(key)
+ p.append(key)
+
+ out = []
+ for item in p:
+ v = self.db_tree.get(item)
+ out.append((item.encode('hex'), v.encode('hex')))
+
+ return out
+
+
+ def get_balance(self, addr):
+ key = self.address_to_key(addr)
+ i = self.db_tree.iterator(start=key)
+ k, _ = i.next()
+ if not k.startswith(key):
+ return 0
+ p = self.get_parent(k)
+ d = self.get_node(p)
+ letter = k[len(p)]
+ return d[letter][1]
+
+
+ def listunspent(self, addr):
+ key = self.address_to_key(addr)
+
+ out = []
+ for k, v in self.db_tree.iterator(start=key):
+ if not k.startswith(key):
+ break
+ if len(k) == KEYLENGTH:
+ txid = k[20:52].encode('hex')
+ txpos = hex_to_int(k[52:56])
+ h = hex_to_int(v[8:12])
+ v = hex_to_int(v[0:8])
+ out.append({'tx_hash': txid, 'tx_pos':txpos, 'height': h, 'value':v})
+
+ out.sort(key=lambda x:x['height'])
+ return out
+
+
def get_history(self, addr):
- addr = self.address_to_key(addr)
- x = self.db_tree.get(addr)
- if x is None:
- return ''
- try:
- _hash, v, h = x
- return h
- except:
- traceback.print_exc(file=sys.stdout)
- self.shared.stop()
- raise
+ out = []
+
+ o = self.listunspent(addr)
+ for item in o:
+ out.append((item['tx_hash'], item['height']))
+
+ h = self.db_hist.get(addr)
+
+ while h:
+ item = h[0:80]
+ h = h[80:]
+ txi = item[0:32].encode('hex')
+ hi = hex_to_int(item[36:40])
+ txo = item[40:72].encode('hex')
+ ho = hex_to_int(item[76:80])
+ out.append((txi, hi))
+ out.append((txo, ho))
+
+ # sort
+ out.sort(key=lambda x:x[1])
+
+ # uniqueness
+ out = set(out)
+
+ return map(lambda x: {'tx_hash':x[0], 'height':x[1]}, out)
+
def get_address(self, txi):