def listunspent(self, addr): key = self.address_to_key(addr) if key is None: raise BaseException('Invalid Bitcoin address', addr) out = [] with self.db_utxo.lock: for k, v in self.db_utxo.db.iterator(start=key): if not k.startswith(key): break if len(k) == KEYLENGTH: txid = k[20:52].encode('hex') txpos = bytes4_to_int(k[52:56]) h = bytes4_to_int(v[8:12]) v = bytes8_to_int(v[0:8]) out.append({ 'tx_hash': txid, 'tx_pos': txpos, 'height': h, 'value': v }) if len(out) == 1000: print_log('max utxo reached', addr) break out.sort(key=lambda x: x['height']) return out
def delete_key(self, leaf): path = self.get_path(leaf) #print "delete key", leaf.encode('hex'), map(lambda x: x.encode('hex'), path) s = self.db_utxo.get(leaf) self.db_utxo.delete(leaf) if leaf in self.hash_list: del self.hash_list[leaf] parent = path[-1] letter = leaf[len(parent)] parent_node = self.get_node(parent) parent_node.remove(letter) # remove key if it has a single child if parent_node.is_singleton(parent): #print "deleting parent", parent.encode('hex') self.db_utxo.delete(parent) if parent in self.hash_list: del self.hash_list[parent] l = parent_node.get_singleton() _hash, value = parent_node.get(l) skip = self.get_skip(parent + l) otherleaf = parent + l + skip # update skip value in grand-parent gp = path[-2] gp_items = self.get_node(gp) letter = otherleaf[len(gp)] new_skip = otherleaf[len(gp) + 1:] gp_items.set(letter, None, 0) self.set_skip(gp + letter, new_skip) #print "gp new_skip", gp.encode('hex'), new_skip.encode('hex') self.put_node(gp, gp_items) # note: k is not necessarily a leaf if len(otherleaf) == KEYLENGTH: ss = self.db_utxo.get(otherleaf) _hash, value = otherleaf[20:52], bytes8_to_int(ss[0:8]) else: _hash, value = None, None self.update_node_hash(otherleaf, path[:-1], _hash, value) else: self.put_node(parent, parent_node) _hash, value = None, None self.update_node_hash(parent, path[:-1], _hash, value) return s
def delete_key(self, leaf): path = self.get_path(leaf) #print "delete key", leaf.encode('hex'), map(lambda x: x.encode('hex'), path) s = self.db_utxo.get(leaf) self.db_utxo.delete(leaf) if leaf in self.hash_list: del self.hash_list[leaf] parent = path[-1] letter = leaf[len(parent)] parent_node = self.get_node(parent) parent_node.remove(letter) # remove key if it has a single child if parent_node.is_singleton(parent): #print "deleting parent", parent.encode('hex') self.db_utxo.delete(parent) if parent in self.hash_list: del self.hash_list[parent] l = parent_node.get_singleton() _hash, value = parent_node.get(l) skip = self.get_skip(parent + l) otherleaf = parent + l + skip # update skip value in grand-parent gp = path[-2] gp_items = self.get_node(gp) letter = otherleaf[len(gp)] new_skip = otherleaf[len(gp)+1:] gp_items.set(letter, None, 0) self.set_skip(gp+ letter, new_skip) #print "gp new_skip", gp.encode('hex'), new_skip.encode('hex') self.put_node(gp, gp_items) # note: k is not necessarily a leaf if len(otherleaf) == KEYLENGTH: ss = self.db_utxo.get(otherleaf) _hash, value = otherleaf[20:52], bytes8_to_int(ss[0:8]) else: _hash, value = None, None self.update_node_hash(otherleaf, path[:-1], _hash, value) else: self.put_node(parent, parent_node) _hash, value = None, None self.update_node_hash(parent, path[:-1], _hash, value) return s
def set_spent(self, addr, txi, txid, index, height, undo): key = self.address_to_key(addr) leaf = key + txi s = self.delete_key(leaf) value = bytes8_to_int(s[0:8]) in_height = bytes4_to_int(s[8:12]) undo[leaf] = value, in_height # delete backlink txi-> addr self.db_addr.delete(txi) # add to history s = self.db_hist.get(addr) if s is None: s = '' txo = (txid + int_to_hex4(index) + int_to_hex4(height)).decode('hex') s += txi + int_to_bytes4(in_height) + txo s = s[-80 * self.pruning_limit:] self.db_hist.put(addr, s)
def set_spent(self, addr, txi, txid, index, height, undo): key = self.address_to_key(addr) leaf = key + txi s = self.delete_key(leaf) value = bytes8_to_int(s[0:8]) in_height = bytes4_to_int(s[8:12]) undo[leaf] = value, in_height # delete backlink txi-> addr self.db_addr.delete(txi) # add to history s = self.db_hist.get(addr) if s is None: s = '' txo = (txid + int_to_hex4(index) + int_to_hex4(height)).decode('hex') s += txi + int_to_bytes4(in_height) + txo s = s[ -80*self.pruning_limit:] self.db_hist.put(addr, s)
def get_hash(self, x, parent): if x: assert self.k != 0 skip_string = x[len(parent) + 1:] if x != '' else '' x = 0 v = 0 hh = '' for i in xrange(256): if (self.k & (1 << i)) != 0: ss = self.s[x:x + 40] hh += ss[0:32] v += bytes8_to_int(ss[32:40]) x += 40 try: _hash = Hash(skip_string + hh) except: _hash = None if x: assert self.k != 0 return _hash, v
def get_hash(self, x, parent): if x: assert self.k != 0 skip_string = x[len(parent)+1:] if x != '' else '' x = 0 v = 0 hh = '' for i in xrange(256): if (self.k&(1<<i)) != 0: ss = self.s[x:x+40] hh += ss[0:32] v += bytes8_to_int(ss[32:40]) x += 40 try: _hash = Hash(skip_string + hh) except: _hash = None if x: assert self.k != 0 return _hash, v
def listunspent(self, addr): key = self.address_to_key(addr) if key is None: raise BaseException('Invalid Reddcoin address', addr) out = [] with self.db_utxo.lock: for k, v in self.db_utxo.db.iterator(start=key): if not k.startswith(key): break if len(k) == KEYLENGTH: txid = k[20:52].encode('hex') txpos = bytes4_to_int(k[52:56]) h = bytes4_to_int(v[8:12]) v = bytes8_to_int(v[0:8]) out.append({'tx_hash': txid, 'tx_pos':txpos, 'height': h, 'value':v}) if len(out) == 1000: print_log('max utxo reached', addr) break out.sort(key=lambda x:x['height']) return out
def listunspent(self, addr): key = self.address_to_key(addr) if key is None: raise BaseException("Invalid Bitcoin address", addr) out = [] with self.db_utxo.lock: for k, v in self.db_utxo.db.iterator(start=key): if not k.startswith(key): break if len(k) == KEYLENGTH: txid = k[20:52].encode("hex") txpos = bytes4_to_int(k[52:56]) h = bytes4_to_int(v[8:12]) v = bytes8_to_int(v[0:8]) out.append({"tx_hash": txid, "tx_pos": txpos, "height": h, "value": v}) if len(out) == 1000: print_log("max utxo reached", addr) break out.sort(key=lambda x: x["height"]) return out
def get(self, c): x = self.indexof(c) ss = self.s[x:x + 40] _hash = ss[0:32] value = bytes8_to_int(ss[32:40]) return _hash, value
def get_utxo_value(self, addr, txi): key = self.address_to_key(addr) leaf = key + txi s = self.db_utxo.get(leaf) value = bytes8_to_int(s[0:8]) return value
def get(self, c): x = self.indexof(c) ss = self.s[x:x+40] _hash = ss[0:32] value = bytes8_to_int(ss[32:40]) return _hash, value