C++ framework for fast blockchain.address.get_history
authorgenjix <fake@lol.u>
Fri, 20 Apr 2012 15:38:13 +0000 (16:38 +0100)
committergenjix <fake@lol.u>
Fri, 20 Apr 2012 15:38:13 +0000 (16:38 +0100)
backends/libbitcoin/Makefile [new file with mode: 0644]
backends/libbitcoin/h1.py [new file with mode: 0644]
backends/libbitcoin/history.cpp [new file with mode: 0644]
backends/libbitcoin/history1/__init__.py [new file with mode: 0644]

diff --git a/backends/libbitcoin/Makefile b/backends/libbitcoin/Makefile
new file mode 100644 (file)
index 0000000..3f44322
--- /dev/null
@@ -0,0 +1,6 @@
+CC = g++ -fPIC -Wall -ansi `pkg-config --cflags libbitcoin` -I/usr/include/python2.7 
+
+default:
+       $(CC) -c history.cpp -o history.o
+       $(CC) -shared -Wl,-soname,_history.so history.o -lpython2.7 -lboost_python `pkg-config --libs libbitcoin` -lboost_thread -o history1/_history.so
+
diff --git a/backends/libbitcoin/h1.py b/backends/libbitcoin/h1.py
new file mode 100644 (file)
index 0000000..1a90b28
--- /dev/null
@@ -0,0 +1,17 @@
+import bitcoin
+import history1 as history
+
+def blockchain_started(ec, chain):
+    print "Blockchain initialisation:", ec
+
+def finish(ec):
+    print "Finish:", ec
+
+a = bitcoin.async_service(1)
+chain = bitcoin.bdb_blockchain(a, "/home/genjix/libbitcoin/database",
+                               blockchain_started)
+txpool = bitcoin.transaction_pool(a, chain)
+address = "1Jqu2PVGDvNv4La113hgCJsvRUCDb3W65D"
+history.payment_history(a, chain, txpool, address, finish)
+raw_input()
+
diff --git a/backends/libbitcoin/history.cpp b/backends/libbitcoin/history.cpp
new file mode 100644 (file)
index 0000000..9cc5cd5
--- /dev/null
@@ -0,0 +1,84 @@
+#include <system_error>
+
+#include <bitcoin/bitcoin.hpp>
+using namespace libbitcoin;
+
+#include <boost/python.hpp>
+namespace python = boost::python;
+
+#include "/home/genjix/python-bitcoin/src/primitive.h"
+
+typedef std::function<void (const std::error_code&)> finish_handler;
+
+namespace ph = std::placeholders;
+
+class query_history
+  : public std::enable_shared_from_this<query_history>
+{
+public:
+    query_history(async_service& service,
+        blockchain_ptr chain, transaction_pool_ptr txpool)
+      : strand_(service.get_service()), chain_(chain),
+        txpool_(txpool), stopped_(false)
+    {
+    }
+
+    void start(const std::string& address, finish_handler handle_finish)
+    {
+        address_.set_encoded(address);
+        handle_finish_ = handle_finish;
+        chain_->fetch_outputs(address_,
+            strand_.wrap(std::bind(&query_history::start_loading,
+                shared_from_this(), ph::_1, ph::_2)));
+    }
+
+private:
+    // Not thread-safe
+    void stop()
+    {
+        BITCOIN_ASSERT(stopped_ == false);
+        stopped_ = true;
+    }
+
+    void start_loading(const std::error_code& ec,
+        const message::output_point_list& outpoints)
+    {
+        handle_finish_(ec);
+    }
+
+    io_service::strand strand_;
+
+    blockchain_ptr chain_;
+    transaction_pool_ptr txpool_;
+    bool stopped_;
+
+    payment_address address_;
+    finish_handler handle_finish_;
+};
+
+typedef std::shared_ptr<query_history> query_history_ptr;
+
+void keep_query_alive_proxy(const std::error_code& ec,
+    python::object handle_finish, query_history_ptr history)
+{
+    pyfunction<const std::error_code&> f(handle_finish);
+    f(ec);
+}
+
+void payment_history(async_service_ptr service, blockchain_ptr chain,
+    transaction_pool_ptr txpool, const std::string& address,
+    python::object handle_finish)
+{
+    query_history_ptr history =
+        std::make_shared<query_history>(*service, chain, txpool);
+    history->start(address,
+        std::bind(keep_query_alive_proxy, ph::_1,
+            handle_finish, history));
+}
+
+BOOST_PYTHON_MODULE(_history)
+{
+    using namespace boost::python;
+    def("payment_history", payment_history);
+}
+
diff --git a/backends/libbitcoin/history1/__init__.py b/backends/libbitcoin/history1/__init__.py
new file mode 100644 (file)
index 0000000..9fc479f
--- /dev/null
@@ -0,0 +1,11 @@
+import _history
+from bitcoin import bind, _1
+
+def wrap_finish(handle_finish, ec):
+    handle_finish(ec)
+
+def payment_history(service, chain, txpool, address, finish):
+    _history.payment_history(service.internal_ptr, chain.internal_ptr,
+                             txpool.internal_ptr, address,
+                             bind(wrap_finish, finish, _1))
+