def test_simple_case(): a = [] b = [a] c = [a, b] for perm in permutations([a, b, c]): result = list(toposorted(perm, lambda x: x)) assert_list_equal([a, b, c], result)
def test_disjoint_case(): a = [] b = [a] c = [a] d = [] abcd = [a, b, c, d] for perm in permutations(abcd): result = list(toposorted(perm, lambda x: x)) for x in abcd: assert_in(x, abcd) assert_true(result.index(a) < result.index(b)) assert_true(result.index(a) < result.index(c))
def sort_txs(self, tx_list): block_txs = {h:self.get_tx(h) for h in tx_list} def get_dependent_txs(tx): """all transactions from current block this transaction directly depends on""" dependent_txs = [] for inp in tx.inputs: if inp.prevout.hash in block_txs: dependent_txs.append(block_txs[inp.prevout.hash]) return dependent_txs return toposorted(block_txs.values(), get_dependent_txs)
def sort_txs(self, tx_list): block_txs = {h: self.get_tx(h) for h in tx_list} def get_dependent_txs(tx): """all transactions from current block this transaction directly depends on""" dependent_txs = [] for inp in tx.inputs: if inp.prevout.hash in block_txs: dependent_txs.append(block_txs[inp.prevout.hash]) return dependent_txs return toposorted(block_txs.values(), get_dependent_txs)
def scan_blockchain(self, blocklist): txo = self.colordef.genesis.copy() txo["blockhash"] = self.genesis_blockhash txo_queue = [txo] for blockhash in blocklist: if self.metastore.did_scan(self.color_id, blockhash): continue # remove txs from this block from the queue block_txo_queue = [ txo for txo in txo_queue if txo.get('blockhash') == blockhash ] txo_queue = [ txo for txo in txo_queue if txo.get('blockhash') != blockhash ] block_txos = {} while block_txo_queue: txo = block_txo_queue.pop() if txo['txhash'] in block_txos: continue block_txos[txo['txhash']] = txo spends = get_spends(txo['txhash'], self.blockchain_state) for stxo in spends: if stxo['blockhash'] == blockhash: block_txo_queue.append(stxo) else: txo_queue.append(stxo) block_txs = {} for txhash in block_txos.keys(): block_txs[txhash] = self.blockchain_state.get_tx(txhash) def get_prev_txs(tx): """all transactions from current block this transaction directly depends on""" prev_txs = [] for inp in tx.inputs: if inp.prevout.hash in block_txs: prev_txs.append(block_txs[inp.prevout.hash]) return prev_txs sorted_block_txs = toposorted(block_txs.values(), get_prev_txs) for tx in sorted_block_txs: self.scan_tx(tx) self.metastore.set_as_scanned(self.color_id, blockhash)
def scan_blockchain(self, blocklist): txo = self.colordef.genesis.copy() txo["blockhash"] = self.genesis_blockhash txo_queue = [txo] for blockhash in blocklist: if self.metastore.did_scan(self.color_id, blockhash): continue # remove txs from this block from the queue block_txo_queue = [txo for txo in txo_queue if txo.get('blockhash') == blockhash] txo_queue = [txo for txo in txo_queue if txo.get('blockhash') != blockhash] block_txos = {} while block_txo_queue: txo = block_txo_queue.pop() if txo['txhash'] in block_txos: continue block_txos[txo['txhash']] = txo spends = get_spends(txo['txhash'], self.blockchain_state) for stxo in spends: if stxo['blockhash'] == blockhash: block_txo_queue.append(stxo) else: txo_queue.append(stxo) block_txs = {} for txhash in block_txos.keys(): block_txs[txhash] = self.blockchain_state.get_tx(txhash) def get_prev_txs(tx): """all transactions from current block this transaction directly depends on""" prev_txs = [] for inp in tx.inputs: if inp.prevout.hash in block_txs: prev_txs.append(block_txs[inp.prevout.hash]) return prev_txs sorted_block_txs = toposorted(block_txs.values(), get_prev_txs) for tx in sorted_block_txs: self.scan_tx(tx) self.metastore.set_as_scanned(self.color_id, blockhash)
def scan_blockchain(self, from_height, to_height): txo_queue = [self.colordef.genesis] for cur_block_height in xrange(self.colordef.starting_height, to_height + 1): # remove txs from this block from the queue block_txo_queue = [ txo for txo in txo_queue if txo['height'] == cur_block_height ] txo_queue = [ txo for txo in txo_queue if txo['height'] != cur_block_height ] block_txos = {} while block_txo_queue: txo = block_txo_queue.pop() if txo['txhash'] in block_txos: # skip the ones we have already visited continue block_txos[txo['txhash']] = txo spends = get_spends(txo['txhash'], self.blockchain_state) for stxo in spends: if stxo['height'] == cur_block_height: block_txo_queue.append(stxo) else: txo_queue.append(stxo) block_txs = {} for txhash in block_txos.keys(): block_txs[txhash] = self.blockchain_state.get_tx(txhash) def get_prev_txs(tx): """all transactions from current block this transaction directly depends on""" prev_txs = [] for inp in tx.inputs: if inp.outpoint.hash in block_txs: prev_txs.append(block_txs[inp.outpoint.hash]) return prev_txs sorted_block_txs = toposorted(block_txs.values(), get_prev_txs) for tx in sorted_block_txs: self.scan_tx(tx)
def scan_blockchain(self, from_height, to_height): txo_queue = [self.colordef.genesis] for cur_block_height in xrange(self.colordef.starting_height, to_height + 1): # remove txs from this block from the queue block_txo_queue = [txo for txo in txo_queue if txo['height'] == cur_block_height] txo_queue = [txo for txo in txo_queue if txo['height'] != cur_block_height] block_txos = {} while block_txo_queue: txo = block_txo_queue.pop() if txo['txhash'] in block_txos: # skip the ones we have already visited continue block_txos[txo['txhash']] = txo spends = get_spends(txo['txhash'], self.blockchain_state) for stxo in spends: if stxo['height'] == cur_block_height: block_txo_queue.append(stxo) else: txo_queue.append(stxo) block_txs = {} for txhash in block_txos.keys(): block_txs[txhash] = self.blockchain_state.get_tx(txhash) def get_prev_txs(tx): """all transactions from current block this transaction directly depends on""" prev_txs = [] for inp in tx.inputs: if inp.outpoint.hash in block_txs: prev_txs.append(block_txs[inp.outpoint.hash]) return prev_txs sorted_block_txs = toposorted(block_txs.values(), get_prev_txs) for tx in sorted_block_txs: self.scan_tx(tx)
def test_cyclical_case(): a = ('a', []) b = ('b', [a]) a[1].append(b) toposorted([a, b], lambda x: x[1])