class TestStore(unittest.TestCase): def setUp(self): self.dsc = DataStoreConnection(":memory:") self.store = ColorDataStore(self.dsc.conn) self.persistent = PersistentDictStore(self.dsc.conn, 'per') self.meta = ColorMetaStore(self.dsc.conn) def test_autocommit(self): path = "/tmp/tmp.db" c = DataStoreConnection(path, True) self.assertFalse(c.conn.isolation_level) os.remove(path) def test_table_exists(self): self.assertFalse(self.store.table_exists('notthere')) def test_sync(self): self.assertFalse(self.store.sync()) def test_transaction(self): self.assertEqual(self.store.transaction(), self.dsc.conn) def test_colordata(self): self.assertFalse(self.store.get(1, "1", 0)) self.assertFalse(self.store.get_any("1", 0)) self.assertFalse(self.store.get_all(1)) self.store.add(1, "1", 0, 1, "test0") self.assertTrue(self.store.get(1, "1", 0)) self.assertTrue(self.store.get_any("1", 0)) self.assertTrue(self.store.get_all(1)) self.store.remove(1, "1", 0) self.assertFalse(self.store.get(1, "1", 0)) self.assertFalse(self.store.get_any("1", 0)) self.assertFalse(self.store.get_all(1)) def test_persistent(self): self.assertFalse(self.persistent.get("tmp")) self.persistent['tmp'] = 1 self.assertTrue(self.persistent.get("tmp")) self.assertEqual(self.persistent.keys(), ['tmp']) del self.persistent['tmp'] self.assertFalse(self.persistent.get("tmp")) self.assertRaises(KeyError, self.persistent.__delitem__, 'tmp') def test_meta(self): self.assertFalse(self.meta.did_scan(1, "hash")) self.meta.set_as_scanned(1, "hash") self.assertTrue(self.meta.did_scan(1, "hash")) self.assertFalse(self.meta.find_color_desc(1)) self.meta.resolve_color_desc("color", True) self.assertTrue(self.meta.find_color_desc(1))
def __init__(self, model): self.model = model self.entries = PersistentDictStore(self.model.store_conn.conn, "txhistory")
class TxHistory(object): def __init__(self, model): self.model = model self.entries = PersistentDictStore(self.model.store_conn.conn, "txhistory") def decode_entry(self, entry_data): print('entry_data', entry_data) return TxHistoryEntry.from_data(self.model, entry_data) def get_entry(self, txhash): entry = self.entries.get(txhash) if entry: return self.decode_entry(entry) else: return None def add_send_entry(self, txhash, asset, target_addrs, target_values): self.entries[txhash] = { "txhash": txhash, "txtype": 'send', "txtime": int(time.time()), "asset_id": asset.get_id(), "targets": zip(target_addrs, target_values) } def get_all_entries(self): return sorted([self.decode_entry(e) for e in self.entries.values()], key=lambda txe: txe.txtime) def populate_history(self): txdb = self.model.get_tx_db() for txhash in txdb.get_all_tx_hashes(): if txhash not in self.entries: tx_data = txdb.get_tx_by_hash(txhash)['data'] raw_tx = RawTxSpec.from_tx_data(self.model, tx_data.decode('hex')) self.add_entry_from_tx(raw_tx) def add_receive_entry(self, txhash, received_coins): out_idxs = [coin.outindex for coin in received_coins] self.entries[txhash] = { "txhash": txhash, "txtype": 'receive', "txtime": int(time.time()), # TODO !!! "out_idxs": out_idxs } def add_trade_entry(self, txhash, in_colorvalue, out_colorvalue): adm = self.model.get_asset_definition_manager() in_assetvalue = adm.get_asset_value_for_colorvalue(in_colorvalue) out_assetvalue = adm.get_asset_value_for_colorvalue(out_colorvalue) self.entries[txhash] = { "txhash": txhash, "txtype": 'trade', "txtime": int(time.time()), "in_values": [asset_value_to_data(in_assetvalue)], "out_values": [asset_value_to_data(out_assetvalue)] } def add_unknown_entry(self, txhash): self.entries[txhash] = { "txhash": txhash, "txtype": 'unknown', "txtime": int(time.time()) } def add_entry_from_tx(self, raw_tx): coindb = self.model.get_coin_manager() spent_coins, received_coins = coindb.get_coins_for_transaction(raw_tx) if (not spent_coins) and (not received_coins): return if not spent_coins: self.add_receive_entry(raw_tx.get_hex_txhash(), received_coins) else: # TODO: classify p2ptrade and send transactions self.add_unknown_entry(raw_tx.get_hex_txhash())
def __init__(self, model): self.model = model self.entries = PersistentDictStore( self.model.store_conn.conn, "txhistory")
class TxHistory(object): def __init__(self, model): self.model = model self.entries = PersistentDictStore( self.model.store_conn.conn, "txhistory") def decode_entry(self, entry_data): return TxHistoryEntry.from_data(self.model, entry_data) def get_entry(self, txhash): entry = self.entries.get(txhash) if entry: return self.decode_entry(entry) else: return None def get_all_entries(self): return sorted([self.decode_entry(e) for e in self.entries.values()], key=lambda txe: txe.txtime) def populate_history(self): txdb = self.model.get_tx_db() for txhash in txdb.get_all_tx_hashes(): if (txhash not in self.entries or # new transaction not self.entries[txhash]['txtime']): # update unconfirmed tx_data = txdb.get_tx_by_hash(txhash)['data'] raw_tx = RawTxSpec.from_tx_data(self.model, tx_data.decode('hex')) self.add_entry_from_tx(raw_tx) def get_tx_timestamp(self, txhash): # TODO move to suitable file txtime = 0 bs = self.model.get_blockchain_state() blockhash, x = bs.get_tx_blockhash(txhash) if blockhash: height = bs.get_block_height(blockhash) if height: header = bs.get_header(height) txtime = header.get('timestamp', txtime) return txtime def is_receive_entry(self, raw_tx, spent_coins, received_coins): return not spent_coins and received_coins def create_receive_entry(self, raw_tx, received_coins): txhash = raw_tx.get_hex_txhash() txtime = self.get_tx_timestamp(txhash) out_idxs = [coin.outindex for coin in received_coins] self.entries[txhash] = {"txhash": txhash, "txtype": 'receive', "txtime": txtime, "out_idxs": out_idxs} def add_trade_entry(self, txhash, in_colorvalue, out_colorvalue): adm = self.model.get_asset_definition_manager() in_assetvalue = adm.get_assetvalue_for_colorvalue(in_colorvalue) out_assetvalue = adm.get_assetvalue_for_colorvalue(out_colorvalue) txtime = self.get_tx_timestamp(txhash) self.entries[txhash] = {"txhash": txhash, "txtype": 'trade', "txtime": txtime, "in_values": [asset_value_to_data(in_assetvalue)], "out_values": [asset_value_to_data(out_assetvalue)]} def add_unknown_entry(self, txhash): txtime = self.get_tx_timestamp(txhash) self.entries[txhash] = {"txhash": txhash, "txtype": 'unknown', "txtime": txtime} def get_delta_color_values(self, spent_coins, received_coins): adm = self.model.get_asset_definition_manager() deltas = {} for coin in received_coins: # add received for cv in coin.get_colorvalues(): colorid = cv.get_colordef().get_color_id() assetid = adm.get_asset_by_color_id(colorid).get_id() deltas[assetid] = deltas.get(assetid, 0) + cv.get_value() for coin in spent_coins: # subtract sent for cv in coin.get_colorvalues(): colorid = cv.get_colordef().get_color_id() assetid = adm.get_asset_by_color_id(colorid).get_id() deltas[assetid] = deltas.get(assetid, 0) - cv.get_value() return dict(deltas) def create_complex_entry(self, raw_tx, spent_coins, received_coins): am = self.model.get_address_manager() txhash = raw_tx.get_hex_txhash() txtime = self.get_tx_timestamp(txhash) # get addresses outputs = raw_tx.composed_tx_spec.txouts wallet_addrs = set([r.address for r in am.get_all_addresses()]) output_addrs = set([out.target_addr for out in outputs]) send_addrs = list(output_addrs.difference(wallet_addrs)) deltas = self.get_delta_color_values(spent_coins, received_coins) self.entries[txhash] = { "txhash": txhash, "txtype": 'complex', "txtime": txtime, "addresses" : send_addrs, "deltas" : deltas, } def is_send_entry(self, raw_tx, spent_coins, received_coins): am = self.model.get_address_manager() # only inputs from this wallet input_addrs = set(raw_tx.get_input_addresses()) wallet_addrs = set([r.address for r in am.get_all_addresses()]) if wallet_addrs.intersection(input_addrs) != input_addrs: return False # foreign inputs # only one color + uncolored sent cvlists = [coin.get_colorvalues() for coin in spent_coins] cvs = [item for sublist in cvlists for item in sublist] # flatten cids = set([cv.get_color_id() for cv in cvs]) if len(cids) > 2 or (len(cids) == 2 and 0 not in cids): return False return False # FIXME disabled for now def create_send_entry(self, raw_tx, spent_coins, received_coins): pass # TODO def add_send_entry(self, txhash, asset, target_addrs, target_values): self.entries[txhash] = {"txhash": txhash, "txtype": 'send', "txtime": int(time.time()), "asset_id": asset.get_id(), "targets": zip(target_addrs, target_values)} def add_entry_from_tx(self, raw_tx): coindb = self.model.get_coin_manager() spent_coins, received_coins = coindb.get_coins_for_transaction(raw_tx) if (not spent_coins) and (not received_coins): return # no effect # receive coins if self.is_receive_entry(raw_tx, spent_coins, received_coins): self.create_receive_entry(raw_tx, received_coins) # send coins elif self.is_send_entry(raw_tx, spent_coins, received_coins): self.create_send_entry(raw_tx, spent_coins, received_coins) else: # default for non obvious self.create_complex_entry(raw_tx, spent_coins, received_coins)
class TxHistory(object): def __init__(self, model): self.model = model self.entries = PersistentDictStore( self.model.store_conn.conn, "txhistory") def decode_entry(self, entry_data): print ('entry_data', entry_data) return TxHistoryEntry.from_data(self.model, entry_data) def get_entry(self, txhash): entry = self.entries.get(txhash) if entry: return self.decode_entry(entry) else: return None def add_send_entry(self, txhash, asset, target_addrs, target_values): self.entries[txhash] = {"txhash": txhash, "txtype": 'send', "txtime": int(time.time()), "asset_id": asset.get_id(), "targets": zip(target_addrs, target_values)} def get_all_entries(self): return sorted([self.decode_entry(e) for e in self.entries.values()], key=lambda txe: txe.txtime) def populate_history(self): txdb = self.model.get_tx_db() for txhash in txdb.get_all_tx_hashes(): if txhash not in self.entries: tx_data = txdb.get_tx_by_hash(txhash)['data'] raw_tx = RawTxSpec.from_tx_data(self.model, tx_data.decode('hex')) self.add_entry_from_tx(raw_tx) def add_receive_entry(self, txhash, received_coins): out_idxs = [coin.outindex for coin in received_coins] self.entries[txhash] = {"txhash": txhash, "txtype": 'receive', "txtime": int(time.time()), # TODO !!! "out_idxs": out_idxs} def add_trade_entry(self, txhash, in_colorvalue, out_colorvalue): adm = self.model.get_asset_definition_manager() in_assetvalue = adm.get_asset_value_for_colorvalue(in_colorvalue) out_assetvalue = adm.get_asset_value_for_colorvalue(out_colorvalue) self.entries[txhash] = {"txhash": txhash, "txtype": 'trade', "txtime": int(time.time()), "in_values": [asset_value_to_data(in_assetvalue)], "out_values": [asset_value_to_data(out_assetvalue)]} def add_unknown_entry(self, txhash): self.entries[txhash] = {"txhash": txhash, "txtype": 'unknown', "txtime": int(time.time())} def add_entry_from_tx(self, raw_tx): coindb = self.model.get_coin_manager() spent_coins, received_coins = coindb.get_coins_for_transaction(raw_tx) if (not spent_coins) and (not received_coins): return if not spent_coins: self.add_receive_entry(raw_tx.get_hex_txhash(), received_coins) else: # TODO: classify p2ptrade and send transactions self.add_unknown_entry(raw_tx.get_hex_txhash())
def setUp(self): self.dsc = DataStoreConnection(":memory:") self.store = ColorDataStore(self.dsc.conn) self.persistent = PersistentDictStore(self.dsc.conn, 'per') self.meta = ColorMetaStore(self.dsc.conn)