-
Notifications
You must be signed in to change notification settings - Fork 35
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
Integrate support for 0-conf #26
Comments
This is a good start in considering 0-conf. Some RBF code is probably in bitcoinj and in our current bitcoinj-cash version. That could be removed as part of this project. For 0-conf, there is the sender and the receiver. Both would want confidence in the transaction involved. Some of your proposal is already part of bitcoinj-cash:
Currently as you pointed out, when broadcasting a transaction, the transactions are sent to about half the connected peers and it waits for the other half to respond with an INV message with the hash of the transaction. It also listens for rejected messages. Based on those two responses, it will indicate what will happen with the transaction.
These are not in bitcoinj. I do like your thinking in addressing the limitations. For the Sender: For the Receiver: Some nodes could reject the transaction while others don't based on the configurations of those nodes and other factors. I will need to think on this further. My own app that uses bitcoinj-cash has some limitations in this matter also. It reports confirmations (up to 6 or 7 with a pie chart, visually). If the transaction is rejected by nodes (perhaps for fee or priority reasons) it will say that the Transaction hasn't been broadcast, but doesn't give a reason why. If the app receives inventory messages, then it will say that the transaction has been broadcast. It will be interesting to see where this topic goes. Thanks @rseibane for creating this issue. |
I'm starting to implement this 0-conf approach. I think it's better talk about the details with code some to express this ideas. I have in mind some ways to keep the details of the implementation very flexible and extensible. |
I look forward to seeing what you come up with. |
First commit. It compiles, but I haven't run the tests yet. rafa-js@0adad62 I've just cleanup the broadcast code:
This is the base for the next things to define. Now we have more flexibility to implement concrete parts and well defined concepts within the broadcast process. Please, share your thoughts about this. Let me know if you find any suggestion or you find I'm breaking or forgetting something. |
This looks very interesting. Some concerns are:
At this point I don't see any problems with your ideas. |
Hope to have a new commit at the end of the day. In the meaning while, I have a question about this code block: https://github.com/bitcoinj-cash/bitcoinj/blob/cash-0.14/core/src/main/java/org/bitcoinj/core/TransactionBroadcast.java#L99
Maybe Bitcoin Core and Bitcoin Cash required different answers... |
This is what we have for reasons for rejection. It includes other reasons by besides double-spend.
Some rejections would result from bugs in bitcoinj or the app that uses bitcoinj for not calculating outputs correctly (dust, insufficent fees) or forming the transaction incorrectly (nonstandard, invalid). It is possible that a transaction could be rejected by one node and not another based on the configuration of the node. For instance if a BCH node was set up to require a higher fee, it would reject the transaction, but the other nodes would not. If a new feature is added to transactions, which uses version 3, then older nodes would reject that transaction as non-standard. But upgraded nodes would not reject it. This may not be a big issue with Bitcoin Cash, which has hard forks and therefore older clients won't be on the network. Given that there are multiple reasons for rejection and that nodes can return different results in some cases, that is proabably why bitcoinj current has it rule with half the target number of broadcasts. That doesn't mean that something cannot be improved. Therefore it is necessary to see what multiple nodes return as rejection message and what the other nodes return with inventory messages. Perhaps for Double Spend, you might want to count it rejected if only 1 node returns that error. Again, this is an overview. Specific reasons for each rejection message may give more detail and your implementation could be customized more. |
This details are gold. Is there any place in the bitcoinj code where this codes are already defined? |
Yes, it is here in the |
Thanks for the address. More updates about this: rafa-js@28b42f4 Basically I've included the double-spend checking and started to fit in all the components. Considerations for the double-spend detection:
This is how to broadcast a transaction would look like:
Not sure if you can notice, but now work with futures doesn't look very cool. The reason is that the listener to get news about the broadcast is more complex than what a The next goal is to include a timer to stop listening to the network and consider the broadcast successful in case both the timer is elapsed and any double-spend is detected and we have reached as many peers as our target was set. |
More updates: rafa-js@39ae320 I have included the guard for a few seconds during the broadcast. Now to consider a transaction as successfully broadcasted both the timer has to elapse without detecting and any double-spend and we have to had reached as many peers as our target was set. Additionally, I've included an example to run this, it seems to work fine: https://github.com/rseibane/bitcoinj/blob/0-conf/examples/src/main/java/org/bitcoinj/examples/SendRequestZeroConf.java I've found a problem running some test, but unfortunately I cannot figure out the cause. This is the assert that fails: https://github.com/rseibane/bitcoinj/blob/0-conf/core/src/test/java/org/bitcoinj/core/PeerGroupTransactionBroadcasterTest.java#L255 Probably I will be off for a week or so. Hope to come back with new insights for the implementation. |
I will try to run the tests on your branch and figure out the cause of the test failures. |
There is a A quick fix is this: But peerGroup will still be null. Perhaps there is a better way to do it like create a constructor specifically for the unit test that is not used by other parts of bitcoinj. |
Got it, I understand the way to go. Great insights @HashEngineering |
Fixed the null pointer rafa-js@003fd30, but still the same assertion error:
|
Finally it passes all the tests: rafa-js@20674af Pending issues so far? |
I've find out a weird scenario. During the broadcast process and waiting for the Do you have any idea about this issue? What does the |
Protocol View:
I don't see how receivePending is called under this scenario, unless the new transaction is not added to the pending list of the wallet in before step 1. There are two cases where receivePending is called
I am not sure about your issue. The second case of calling receivePending should be happening, but it sounds like perhaps the first case is happening. In the first case, no updates would be received until other peers announce the transaction, which may not be what you are talking about. |
Thanks for replying so fast @HashEngineering
This is happening in my case, because I don't want to add it unless it has been broadcasted properly. Anyway, I don't see the relation between the invocation to the |
I don't see how Wallet.receivePending is related to not receiving inv messages. The success of a broadcast is measured by the number of inv messages received from the other nodes that the transaction was not sent to. I would need to try out your code with the example to see what is happening with it. |
Now seems like it works. Not sure it was an issue with the code or with the network but the question is it didn't happen any more. Do you think the 0-conf should be always present to anyone who uses the library or just optional? If it was on me I would make it always present just as part of the library. |
I would say it should always be active. |
Overview
As you know, Bitcoin Cash dropped the legacy RBF protocol in order to simplify 0-conf payments. Still not 100% secure since a rival could try different attacks that I personally consider very unlikely, but just my opinion (we can discuss about it if required).
The different Bitcoin Cash wallet, should consider this feature to provide the best user experience. In the future, we should stop using "confirmations" as a common word for payments. To go mainstream we need people and merchants to stop caring about confirmations, they just need to pay done. Does people care about the technical details when they pay using Visa? Not at all.
Since we have a technology that allow us to work this way, I think we should start taking the most from Bitcoin Cash. If we all are integrating 0-conf in our wallets, add this feature to the Bitcoinj-cash library is the way to go: each wallet don't need to reinvent the wheel + we standardise the algorithm to do it.
Just following some comments from Satoshi: https://bitcointalk.org/index.php?topic=423.msg3819#msg3819 and https://bitcointalk.org/index.php?topic=532.msg6306#msg6306.
Some considerations before implement 0-conf
In the big picture we need to:
As far as I understand, this is could be an algorithm to process 0-conf payments, opened to changes, for sure:
Notice any of this parameters could be tuned, depending of the considerations of each wallet. If this is becoming standard, should be flexible enough.
Pending question: what to do in case we find a double-spend after we broadcast?
Bitcoinj-cash currently
As the original bitcoinj project works over Bitcoin Core, and it includes the RBF feature obviously it doesn't consider any of the previous points.
Correct me if I'm wrong but when you include a broadcast transaction listener, it's only invoked if the transaction is accepted by a node, but you can't notice if any node rejects it. This node rejection message remains totally hidden, what makes the previous algorithm a little bit tricky. https://github.com/bitcoinj-cash/bitcoinj/blob/cash-0.14/core/src/main/java/org/bitcoinj/core/TransactionBroadcast.java#L91
Provide a solution to have all the required events over the transactions is a must to implement the a 0-conf algorithm.
Goals
TransactionBroadcaster
https://github.com/bitcoinj-cash/bitcoinj/blob/cash-0.14/core/src/main/java/org/bitcoinj/core/TransactionBroadcaster.java that performs this new logic.broadcastTransaction
method to include a kind of listener to notify the response:BroadcastTransactionListener
. For instance:What is your view for this? Many points to discuss, so please just let out any insight or comment you have.
Regards,
The text was updated successfully, but these errors were encountered: