From a4f64bd1bf8df41f45df8cc45f0d453a3a921658 Mon Sep 17 00:00:00 2001 From: Jude Nelson Date: Mon, 10 Apr 2017 11:49:13 -0400 Subject: [PATCH] renamed old blockstack_utxo to blockstack_core as UTXO endpoint --- .../backend/utxo/blockstack_core.py | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 blockstack_client/backend/utxo/blockstack_core.py diff --git a/blockstack_client/backend/utxo/blockstack_core.py b/blockstack_client/backend/utxo/blockstack_core.py new file mode 100644 index 000000000..e8933d805 --- /dev/null +++ b/blockstack_client/backend/utxo/blockstack_core.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python2 +# -*- coding: utf-8 -*- +""" + Blockstack-client + ~~~~~ + copyright: (c) 2014-2015 by Halfmoon Labs, Inc. + copyright: (c) 2016 by Blockstack.org + + This file is part of Blockstack-client. + + Blockstack-client is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Blockstack-client is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with Blockstack-client. If not, see . +""" + +from .blockchain_client import BlockchainClient + +from xmlrpclib import ServerProxy, Transport +from defusedxml import xmlrpc +import httplib +import json + +# prevent the usual XML attacks +xmlrpc.monkey_patch() + +class BlockstackCoreUTXOClient( BlockchainClient ): + def __init__(self, server, port): + self.type = "blockstack_utxo" + self.server = server + self.port = port + + def get_unspents(self, address): + return get_unspents( address, self ) + + def broadcast_transaction(self, txdata ): + return broadcast_transaction( txdata, self ) + + +# TODO: make into its own module +# https://seattle.poly.edu/browser/seattle/trunk/demokit/timeout_xmlrpclib.py?rev=692 +class TimeoutHTTPConnection(httplib.HTTPConnection): + def connect(self): + httplib.HTTPConnection.connect(self) + self.sock.settimeout(self.timeout) + + +class TimeoutHTTP(httplib.HTTP): + _connection_class = TimeoutHTTPConnection + + def set_timeout(self, timeout): + self._conn.timeout = timeout + + def getresponse(self, **kw): + return self._conn.getresponse(**kw) + + +class TimeoutTransport(Transport): + def __init__(self, *l, **kw): + self.timeout = kw.get('timeout', 10) + if 'timeout' in kw.keys(): + del kw['timeout'] + + Transport.__init__(self, *l, **kw) + + def make_connection(self, host): + conn = TimeoutHTTP(host) + conn.set_timeout(self.timeout) + return conn + +class TimeoutServerProxy(ServerProxy): + def __init__(self, uri, *l, **kw): + kw['transport'] = TimeoutTransport(timeout=kw.get('timeout',10), use_datetime=kw.get('use_datetime', 0)) + if 'timeout' in kw.keys(): + del kw['timeout'] + + ServerProxy.__init__(self, uri, *l, **kw) + + +class BlockstackCoreRPCClient(object): + """ + RPC client for the blockstack server + """ + def __init__(self, server, port, timeout=30 ): + self.srv = TimeoutServerProxy( "http://%s:%s" % (server, port), timeout=timeout, allow_none=True ) + self.server = server + self.port = port + + def __getattr__(self, key): + try: + return object.__getattr__(self, key) + except AttributeError: + def inner(*args, **kw): + func = getattr(self.srv, key) + res = func(*args, **kw) + if res is not None: + # lol jsonrpc within xmlrpc + res = json.loads(res) + return res + return inner + + +def get_unspents( address, client=BlockstackCoreUTXOClient("localhost", 6264) ): + """ + Get unspent outputs from a Blockstack server. + """ + proxy = BlockstackCoreRPCClient( client.server, client.port ) + unspents = proxy.get_unspents( address ) + return unspents + + +def broadcast_transaction( txdata, client ): + """ + Send a transaction through a Blockstack server + """ + if not isinstance(client, BlockstackCoreUTXOClient): + raise Exception("Not a Blockstack UTXO client") + + proxy = BlockstackCoreRPCClient( client.server, client.port ) + res = proxy.broadcast_transaction( txdata ) + return res +