Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

listunspent and import_addresses API methods #249

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM python
WORKDIR /
RUN git clone https://github.com/commerceblock/electrum-personal-server.git
WORKDIR /electrum-personal-server
ADD config.ini config.ini
RUN pip3 install .
CMD ["electrum-personal-server", "config.ini"]
1 change: 0 additions & 1 deletion electrumpersonalserver/server/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,6 @@ def get_scriptpubkeys_to_monitor(rpc, config):
break
spks_to_monitor.append(spks[0])
wal.rewind_one(change)

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove these irrelevant line changes. Or if you want to refactor then open another PR for them.

spks_to_monitor.extend([hashes.address_to_script(addr, rpc)
for addr in watch_only_addresses])
et = time.time()
Expand Down
33 changes: 32 additions & 1 deletion electrumpersonalserver/server/electrumprotocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
import tempfile
import socket
from collections import defaultdict
from electrumpersonalserver.server.deterministicwallet import import_addresses

from electrumpersonalserver.server.hashes import (
hash_merkle_root,
get_status_electrum,
bytes_fmt
bytes_fmt,
address_to_script
)
from .jsonrpc import JsonRpc, JsonRpcError
from electrumpersonalserver.server.peertopeer import tor_broadcast_tx
Expand Down Expand Up @@ -256,6 +258,14 @@ def handle_query(self, query):
+ "hash(address) = " + scrhash)
raise UnknownScripthashError(scrhash)
self._send_response(query, balance)
elif method == "blockchain.scripthash.listunspent":
scrhash = query["params"][0]
utxos = self.txmonitor.get_address_utxos(scrhash)
if utxos == None:
self.logger.warning("Address history not known to server, "
+ "hash(address) = " + scrhash)
raise UnknownScripthashError(scrhash)
self._send_response(query, utxos)
elif method == "server.ping":
self._send_response(query, None)
elif method == "blockchain.headers.subscribe":
Expand Down Expand Up @@ -384,6 +394,7 @@ def handle_query(self, query):
self._send_response(query, result)
elif method == "blockchain.estimatefee":
estimate = self.rpc.call("estimatesmartfee", [query["params"][0]])
self.logger.info('estimate: ' + estimate)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove from this PR please, it's irrelevant. Also I think it conflicts with another edit I made recently.

feerate = 0.0001
if "feerate" in estimate:
feerate = estimate["feerate"]
Expand Down Expand Up @@ -475,7 +486,27 @@ def handle_query(self, query):
except JsonRpcError as e:
error = {"message": repr(e)}
self._send_error(query["id"], error)
elif method == "import_addresses":
addresses = query["params"][0]
rescan_height = False
if len(query["params"]) > 1:
rescan_height = query["params"][1]
if rescan_height < 0:
rescan_height = False
if len(addresses) > 0:
spks_to_monitor = []
spks_to_monitor.extend([address_to_script(addr, self.rpc) for addr in addresses])
self.logger.info("Importing addresses:" + ' '.join(map(str,addresses)) + "...")
import_addresses(self.rpc, spks_to_monitor, [], -1, self.logger)
self.logger.info("end")
if ( rescan_height ):
self.logger.info("Rescanning. . . for progress indicator see the bitcoin node's" + " debug.log file")
self.rpc.call("rescanblockchain", [rescan_height])
self.logger.info("end")
self.txmonitor.build_address_history(spks_to_monitor)
self._send_response(query, { "result": "success"} )
else:
self.logger.error(method)
self.logger.error("*** BUG! Not handling method: " + method
+ " query=" + str(query))

26 changes: 24 additions & 2 deletions electrumpersonalserver/server/transactionmonitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import math
import sys
import logging
import json
from decimal import Decimal
from collections import defaultdict

Expand Down Expand Up @@ -81,6 +82,21 @@ def get_address_balance(self, scrhash):
return {"confirmed": confirmed_balance, "unconfirmed":
unconfirmed_balance}

def get_address_utxos(self, scrhash):
history = self.get_electrum_history(scrhash)
if history == None:
return None
utxos = []
for tx_info in history:
tx = self.rpc.call("gettransaction", [tx_info["tx_hash"]])
txd = self.rpc.call("decoderawtransaction", [tx["hex"]])
for index, output in enumerate(txd["vout"]):
if script_to_scripthash(output["scriptPubKey"]["hex"]
) != scrhash:
continue
utxos.append({"tx_hash": txd["txid"], "tx_pos": index, "value": output["value"], "confirmations": tx["confirmations"]})
return utxos

def subscribe_address(self, scrhash):
if scrhash in self.address_history:
self.address_history[scrhash]["subscribed"] = True
Expand Down Expand Up @@ -192,8 +208,14 @@ def build_address_history(self, monitored_scriptpubkeys):
et = time.time()
logger.info("Found " + str(count) + " txes. History built in "
+ str(et - st) + "sec")
self.address_history = address_history
self.unconfirmed_txes = unconfirmed_txes
if(self.address_history == None):
self.address_history=address_history
else:
self.address_history.update(address_history)
if(self.unconfirmed_txes == None):
self.unconfirmed_txes=unconfirmed_txes
else:
self.unconfirmed_txes.update(unconfirmed_txes)
return True

def get_input_and_output_scriptpubkeys(self, txid):
Expand Down