-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Extract electrumx module #4427
Extract electrumx module #4427
Conversation
You seem to have lost some of the changes I recently made |
I've identified 4 commits of your to which you are referring: Number 1 is addressed in e289880 and 071f782. I might very well be missing other commits or patches. I appreciate the feedback! |
Grepping for get_chunk still has hits. There are none in master. Otherwise looks good |
lib/verifier.py
Outdated
else: | ||
if (tx_hash not in self.requested_merkle | ||
and tx_hash not in self.merkle_roots): | ||
if tx_height == 0 or tx_height > local_height: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you should not let negative tx_heights through; there are some magic numbers in that range; see
Lines 77 to 79 in 12c5474
TX_HEIGHT_LOCAL = -2 | |
TX_HEIGHT_UNCONF_PARENT = -1 | |
TX_HEIGHT_UNCONFIRMED = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, that is surprising. Thanks for pointing that out. Will fix.
lib/synchronizer.py
Outdated
@@ -120,7 +120,7 @@ def on_address_history(self, response): | |||
tx_fees = dict(filter(lambda x:x[1] is not None, tx_fees)) | |||
# Note if the server hasn't been patched to sort the items properly | |||
if hist != sorted(hist, key=lambda x:x[1]): | |||
self.network.interface.print_error("serving improperly sorted address histories") | |||
self.print_error("error: serving improperly sorted address histories") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not that it's criticial but the difference here is that if you called self.network.interface.print_error
, it would actually print which server is doing it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah... I know what I did there. The reason I did this was so I could get rid of the last remaining 'interface' reference. I deemed the upside bigger than the downside. I'll leave the code as is if that is OK with you.
lib/network.py
Outdated
@@ -525,7 +525,7 @@ def _add_recent_server(self, server): | |||
|
|||
def _process_response(self, interface, response, callbacks): | |||
if self.debug: | |||
self.print_error("<--", response) | |||
self.print_error(interface.host, "<--", response) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did you test this? I think it's redundant, it happens already.
see
Line 172 in 12c5474
print_error("[%s]" % self.diagnostic_name(), *msg) |
I left the |
What needs to be done to get this branch merged? (aside from resolving the conflicts) |
@haarts I did not have time to look at it. |
This PR can be seen as a prelude to converting the network code to use asyncio. It would help me a lot if this PR got merged, otherwise my works diverges more and more from master. You can follow my progress on my own branch: https://github.com/haarts/electrum/tree/add-pylibbitcoin |
Given you are subclassing Network to do e-x specific stuff, I am guessing you won't allow libbitcoin/e-x heterogeneous networks. What is your plan for libbitcoin? Will the client connect to multiple libbitcoin instances like with e-x currently, or will it only connect to one which we assume to be trusted? |
Yes, you are correct. I currently do not allow for hetrogeneous networks. Doing the sub classing as implemented however makes it easy to switch implementations. Either The Libbitcoin implementation supports multiple backends and multiple chains. |
I guess you probably already thought this through but is it easier to modify the client to support both backends (e-x and libbitcoin) than, say having some middleware between the electrum client and libbitcoin translate the electrum protocol calls into libbitcoin rpc (or similar)? |
25f3d08
to
569826c
Compare
lib/websockets.py
Outdated
return addr, amount | ||
scripthash = bitcoin.address_to_scripthash(addr) | ||
hash2address[scripthash] = address | ||
return scripthash, amount |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bitcoin
is not imported
instead of hash2address
, you want self.hash2address
addr
instead of address
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit disappointed in myself I missed this. Odd. And fixed.
As to your middleware question; the thought occurred to me. |
lib/websockets.py
Outdated
@@ -34,6 +34,7 @@ | |||
sys.exit("install SimpleWebSocketServer") | |||
|
|||
from . import util | |||
from lib import bitcoin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use a relative import; especially as the package structure is different when running from source and when having the lib installed
( #4279 )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not know that. Will fix.
16a356a
to
73d7445
Compare
I've rebased this PR again. Would it perhaps help if I split this PR up in pieces? It has grown quite a bit. |
This is again a small step in the right direction. The network module is going to accumulate more and more of these simple methods. Once everything is moved into that module, that module is going to be split. Note that I've left the scripts which use scripts/util.py alone. I suspect the same functionality can be reached when using just lib/network.py and that scripts/util.py is obsolete.
This makes the method easier to read.
This class is a subclass of Network and doesn't do anything different at the moment. The idea is to move ElectrumX specifics to this new class.
Much remains to be done but the demarcation is now clear. To do is moving ElectrumX specific attributes to the electrumx module and making the network configurable somehow.
This was quite a serious bug.
It is starting to be hard to keep track of all the loose ends.
The main motivation of doing so is that the websockets module now no longer needs to access the h2addr field on the network module. Removing the deprecated call was a nice bonus.
The backing ElectrumX call is deprecated in favor of blockchain.scripthash.subscribe.
This was fixed earlier but that fix was lost in an aggresive rebase.
Initially I thought that the caller should be responsible for maintaining the mapping between address and scripthash. That made sense b/c callers accessed the mapping in the network module directly. And the dictionary mainting the mapping was accessed by different callers on potentially different threads. Turns out that maintaining that mapping on the caller site involves quite a bit of work. Besides using address instead of scripthash makes sense from the users perspective. The user never thinks in terms of scripthash. The concurrent access is not a huge deal since we're only adding items and reading singular values.
The class is extracted from the Network class. It's a Seperation of Concerns thing. In the end this will make it easier to change the network module. Note that the lock used here is now specific to the callbacks, it used to be shared with the lock used in sending API calls. I think this is clearer.
Doing so clarifies which methods can be used by others and which are strictly for internal use. I've choosen to use a weaker form of signaling visibility by using only one leading underscore b/c I do not want to deviate from the norm set in this project too much. This diff also introduces the 'server_version' API call.
This way the method call does not wait for a response. It's a little odd that the codebase is using two different ways of dealing with responses. One is with callbacks or blocking and the other is a fire and forget mode in which the responses are later tide to callbacks via message IDs.
I've assumed that having a blockchain (which lives on an interface) implied the network is connected. This is not always the case, therefor we need this additional check.
The new name reflects better what it does.
A transaction height can be negative too, see the wallet modules TX_HEIGHT_LOCAL and TX_HEIGHT_UNCONF_PARENT constants.
73d7445
to
ccd6819
Compare
I can still split it up if you guys find that easier. I'll be sure to do so in the future at least. :) |
I'm closing this one in favor of smaller PR's. |
This pull request further clarifies the network module API.
A couple of major things have happened here (non of which impacts functionality):
I would understand if these changes are considered controversial. Read with care.