X-Git-Url: https://git.novaco.in/?p=electrum-server.git;a=blobdiff_plain;f=backends%2Flibbitcoin%2Fhistory.py;h=cc2a7ade537e4858152a5134b9c8518bb086a54c;hp=c9e807d4758b27726a3b0960eb9724ac80255fa7;hb=240db7c28d2e6a0d0078c42f81b2b110615e88c6;hpb=e737e057559f697e1c824188e314eb7e2b95fa47 diff --git a/backends/libbitcoin/history.py b/backends/libbitcoin/history.py index c9e807d..cc2a7ad 100644 --- a/backends/libbitcoin/history.py +++ b/backends/libbitcoin/history.py @@ -1,8 +1,10 @@ +import threading +import time + import bitcoin from bitcoin import bind, _1, _2, _3 -import threading import multimap -import time + class ExpiryQueue(threading.Thread): @@ -23,8 +25,10 @@ class ExpiryQueue(threading.Thread): with self.lock: self.items.append(item) + expiry_queue = ExpiryQueue() + class MemoryPoolBuffer: def __init__(self, txpool, chain, monitor): @@ -48,9 +52,11 @@ class MemoryPoolBuffer: address = bitcoin.payment_address() if address.extract(output.output_script): desc[2].append((idx, str(address))) - self.txpool.store(tx, + self.txpool.store( + tx, bind(self.confirmed, _1, desc), - bind(self.mempool_stored, _1, desc, handle_store)) + bind(self.mempool_stored, _1, desc, handle_store) + ) def mempool_stored(self, ec, desc, handle_store): tx_hash, prevouts, addrs = desc @@ -95,7 +101,7 @@ class MemoryPoolBuffer: pass result = [] for outpoint in output_points: - if self.lookup_input.has_key(str(outpoint)): + if str(outpoint) in self.lookup_input: point = self.lookup_input[str(outpoint)] info = ExtendableDict() info["tx_hash"] = point[0] @@ -103,7 +109,7 @@ class MemoryPoolBuffer: info["is_input"] = 1 info["timestamp"] = self.timestamps[info["tx_hash"]] result.append(info) - if self.lookup_address.has_key(str(address)): + if str(address) in self.lookup_address: addr_points = self.lookup_address[str(address)] for point in addr_points: info = ExtendableDict() @@ -114,6 +120,7 @@ class MemoryPoolBuffer: result.append(info) handle(result) + class PaymentEntry: def __init__(self, output_point): @@ -135,6 +142,7 @@ class PaymentEntry: def has_input(self): return self.input_point is not False + class History: def __init__(self, chain, txpool, membuf): @@ -153,12 +161,11 @@ class History: address = bitcoin.payment_address(address) # To begin we fetch all the outputs (payments in) # associated with this address - self.chain.fetch_outputs(address, - bind(self.check_membuf, _1, _2)) + self.chain.fetch_outputs(address, bind(self.check_membuf, _1, _2)) def stop(self): with self.lock: - assert self._stopped == False + assert self._stopped is False self._stopped = True def stopped(self): @@ -174,8 +181,7 @@ class History: def check_membuf(self, ec, output_points): if self.stop_on_error(ec): return - self.membuf.check(output_points, self.address, - bind(self.start_loading, _1, output_points)) + self.membuf.check(output_points, self.address, bind(self.start_loading, _1, output_points)) def start_loading(self, membuf_result, output_points): if len(membuf_result) == 0 and len(output_points) == 0: @@ -188,15 +194,13 @@ class History: with self.lock: self.statement.append(entry) # Attempt to fetch the spend of this output - self.chain.fetch_spend(outpoint, - bind(self.load_spend, _1, _2, entry)) + self.chain.fetch_spend(outpoint, bind(self.load_spend, _1, _2, entry)) self.load_tx_info(outpoint, entry, False) # Load memory pool transactions with self.lock: self.membuf_result = membuf_result for info in self.membuf_result: - self.txpool.fetch(bitcoin.hash_digest(info["tx_hash"]), - bind(self.load_pool_tx, _1, _2, info)) + self.txpool.fetch(bitcoin.hash_digest(info["tx_hash"]), bind(self.load_pool_tx, _1, _2, info)) def load_spend(self, ec, inpoint, entry): # Need a custom self.stop_on_error(...) as a missing spend @@ -227,7 +231,7 @@ class History: if any(not entry.is_loaded() for entry in self.statement): return # Memory buffer transactions finished loading? - if any(not info.has_key("height") for info in self.membuf_result): + if any("height" not in info for info in self.membuf_result): return # Whole operation completed successfully! Finish up. result = [] @@ -269,16 +273,14 @@ class History: # Before loading the transaction, Stratum requires the hash # of the parent block, so we load the block depth and then # fetch the block header and hash it. - self.chain.fetch_transaction_index(point.hash, - bind(self.tx_index, _1, _2, _3, entry, info)) + self.chain.fetch_transaction_index(point.hash, bind(self.tx_index, _1, _2, _3, entry, info)) def tx_index(self, ec, block_depth, offset, entry, info): if self.stop_on_error(ec): return info["height"] = block_depth # And now for the block hash - self.chain.fetch_block_header_by_depth(block_depth, - bind(self.block_header, _1, _2, entry, info)) + self.chain.fetch_block_header_by_depth(block_depth, bind(self.block_header, _1, _2, entry, info)) def block_header(self, ec, blk_head, entry, info): if self.stop_on_error(ec): @@ -287,8 +289,7 @@ class History: info["block_hash"] = str(bitcoin.hash_block_header(blk_head)) tx_hash = bitcoin.hash_digest(info["tx_hash"]) # Now load the actual main transaction for this input or output - self.chain.fetch_transaction(tx_hash, - bind(self.load_chain_tx, _1, _2, entry, info)) + self.chain.fetch_transaction(tx_hash, bind(self.load_chain_tx, _1, _2, entry, info)) def load_pool_tx(self, ec, tx, info): if self.stop_on_error(ec): @@ -319,8 +320,7 @@ class History: info["block_hash"] = "mempool" self.finish_if_done() create_handler = lambda prevout_index, input_index: \ - bind(self.load_input_pool_tx, _1, _2, - prevout_index, info, input_index) + bind(self.load_input_pool_tx, _1, _2, prevout_index, info, input_index) self.fetch_input_txs(tx, info, create_handler) def load_tx(self, tx, info): @@ -374,8 +374,7 @@ class History: entry.input_loaded = info self.finish_if_done() create_handler = lambda prevout_index, input_index: \ - bind(self.load_input_chain_tx, _1, _2, - prevout_index, entry, info, input_index) + bind(self.load_input_chain_tx, _1, _2, prevout_index, entry, info, input_index) self.fetch_input_txs(tx, info, create_handler) def inputs_all_loaded(self, info_inputs): @@ -418,11 +417,13 @@ class History: info["block_hash"] = "mempool" self.finish_if_done() + def payment_history(chain, txpool, membuf, address, handle_finish): h = History(chain, txpool, membuf) expiry_queue.add(h) h.start(address, handle_finish) + if __name__ == "__main__": ex = bitcoin.satoshi_exporter() tx_a = bitcoin.data_chunk("0100000003d0406a31f628e18f5d894b2eaf4af719906dc61be4fb433a484ed870f6112d15000000008b48304502210089c11db8c1524d8839243803ac71e536f3d876e8265bbb3bc4a722a5d0bd40aa022058c3e59a7842ef1504b1c2ce048f9af2d69bbf303401dced1f68b38d672098a10141046060f6c8e355b94375eec2cc1d231f8044e811552d54a7c4b36fe8ee564861d07545c6c9d5b9f60d16e67d683b93486c01d3bd3b64d142f48af70bb7867d0ffbffffffff6152ed1552b1f2635317cea7be06615a077fc0f4aa62795872836c4182ca0f25000000008b48304502205f75a468ddb08070d235f76cb94c3f3e2a75e537bc55d087cc3e2a1559b7ac9b022100b17e4c958aaaf9b93359f5476aa5ed438422167e294e7207d5cfc105e897ed91014104a7108ec63464d6735302085124f3b7a06aa8f9363eab1f85f49a21689b286eb80fbabda7f838d9b6bff8550b377ad790b41512622518801c5230463dbbff6001ffffffff01c52914dcb0f3d8822e5a9e3374e5893a7b6033c9cfce5a8e5e6a1b3222a5cb010000008c4930460221009561f7206cc98f40f3eab5f3308b12846d76523bd07b5f058463f387694452b2022100b2684ec201760fa80b02954e588f071e46d0ff16562c1ab393888416bf8fcc44014104a7108ec63464d6735302085124f3b7a06aa8f9363eab1f85f49a21689b286eb80fbabda7f838d9b6bff8550b377ad790b41512622518801c5230463dbbff6001ffffffff02407e0f00000000001976a914c3b98829108923c41b3c1ba6740ecb678752fd5e88ac40420f00000000001976a914424648ea6548cc1c4ea707c7ca58e6131791785188ac00000000") @@ -434,8 +435,10 @@ if __name__ == "__main__": def blockchain_started(ec, chain): print "Blockchain initialisation:", ec + def store_tx(ec): print "Tx", ec + def finish(result): print "Finish" if result is None: @@ -449,6 +452,7 @@ if __name__ == "__main__": class FakeMonitor: def tx_stored(self, tx): pass + def tx_confirmed(self, tx): pass @@ -475,4 +479,3 @@ if __name__ == "__main__": #payment_history(chain, txpool, membuf, address[1], finish) raw_input() print "Stopping..." -