+import threading
+import time
+
import bitcoin
from bitcoin import bind, _1, _2, _3
-import threading
import multimap
-import time
+
class ExpiryQueue(threading.Thread):
with self.lock:
self.items.append(item)
+
expiry_queue = ExpiryQueue()
+
class MemoryPoolBuffer:
def __init__(self, txpool, chain, monitor):
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
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]
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()
result.append(info)
handle(result)
+
class PaymentEntry:
def __init__(self, output_point):
def has_input(self):
return self.input_point is not False
+
class History:
def __init__(self, chain, txpool, membuf):
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):
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:
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
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 = []
# 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):
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):
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):
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):
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")
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:
class FakeMonitor:
def tx_stored(self, tx):
pass
+
def tx_confirmed(self, tx):
pass
#payment_history(chain, txpool, membuf, address[1], finish)
raw_input()
print "Stopping..."
-