-
Notifications
You must be signed in to change notification settings - Fork 191
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
Zero Confirmation Forfeits (ZCF) #964
base: master
Are you sure you want to change the base?
Conversation
1de5349
to
58ce9b3
Compare
That was fast. You rock man. Thank you. |
@cculianu: Thanks, but this is far from finished! |
This is the code to generate the forfeit P2SH smart contract scripts.
Add parsing of generic P2SH contract addresses to the transaction code. Note that this still needs a check (maybe?) whether the previous transaction actually had a P2SH output. It is important to notice that a transaction's TXID is recalculated from these values. As unknown scriptSigs need to still produce the right serialization, the serialization code has likewise been changed to always use an input's scriptSig, if available.
This adds support for handling forfeit addresses to the wallet. Two new class members are introduced: forfeit_map: This maps forfeit addresses to their underlying P2PKH address (for which the public key also matches the forfeit address if using the correct P2SH script for scriptSig generation). forfeit_scripts: This maps forfeit addresses to their corresponding P2SH scripts that allow to spend the forfeit addresses as normal P2PKH (or by two sigs in case a miner detects a double-spend). Both of these objects are persisted to the wallet JSON file for easier handling and to cache the transaction parsing results. It also adds support to the various accessor function to more properly represent forfeit addresses. It still misses the transaction generating code as well as the code to extract forfeits from incoming transactions that match the template forfeit P2SH code. This will come in an upcoming commit.
This checks incoming transactions in add_transaction() for forfeit outputs and, if such outputs are found, adds them to the tracking data structures self.forfeit_map and self.forfeit_scripts.
If the configuration variable use_forfeits is set to true, this will generate transaction that have a "ZCF\x00" OP_RETURN marker indicating the use of forfeits as well as having the special forfeit smart contract output to a corresponding P2SH address. The P2SH address is deterministically generated from the transaction's inputs and the change address that is alsoused for the "forfeit change". This means that it is possible to recreate the P2SH contents just by trying reconstruction of all available outputs and checking for a matching P2SH hash.
Note that this comes with a considerable rework and simplification of the listing logic. This might miss some subtlety regarding the address listing and therefore needs careful review.
This shows a green "F" for unconfirmed transactions that have enough forfeit amount for the given received value. FIXME: The amount is currently hardcoded to be a minimum of 1.0 the received value. It probably makes sense to add a configuration dialog for this.
FIXME: This directly changes the configuration variable. Is this an acceptable way to do it?
For signalling problems when generating forfeit transactions. Also remove a superfluous return after an exception is raised.
... instead of throwing an uncontrolled exception later on.
- this show forfeits already when creating a new transaction - it also shows one's owns and other's forfeit contract P2SH addresses in different colors (light blue for own forfeit outputs, pink for those from others)
This is necessary as to not forget about the forfeit addresses so that the balance is shown correctly.
58ce9b3
to
380d725
Compare
Ok, updates:
|
To have it displayed correctly on the preview tab. FIXME: This might create some noise when aborting the transaction generation and using different inputs down the road.
Updated with a configuration dialog for the send and accepted receive forfeit fractions. Needs more testing. |
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.
Three tiny improvements with intention of being "right work".
for addr_list, name in [ | ||
(self.wallet.get_receiving_addresses(), _("Receiving")), | ||
(self.wallet.get_change_addresses(), _("Change")), | ||
(self.wallet.get_forfeit_addresses(), _("Forfeit"))]: |
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.
For readability, and since the iterating list is never modified, I'd suggest using a tuple and defining it before the loop:
addresses_to_name_pairs = (
(self.wallet.get_receiving_addresses(), _("Receiving")),
(self.wallet.get_change_addresses(), _("Change")),
(self.wallet.get_forfeit_addresses(), _("Forfeit")),
)
for addr_list, name in addresses_to_name_pairs:
@@ -3084,12 +3093,57 @@ def on_fiat_address(checked): | |||
fiat_widgets.append((QLabel(_('Show Fiat balance for addresses')), fiat_address_checkbox)) | |||
fiat_widgets.append((QLabel(_('Source')), ex_combo)) | |||
|
|||
|
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.
Nitpicking: why the extra blank line here?
continue | ||
seq_item = QTreeWidgetItem( [ name, '', '', '', '', ''] ) | ||
account_item.addChild(seq_item) | ||
if not had_item_count: # first time we create this widget, auto-expand the default address list |
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.
Inline comments should be separated by at least two spaces from the statement.
Hey guys,
here's my very preliminary code to do zero confirmation forfeits with Electron Cash. This should serve both as a test bed for development of the concept, as well as later on a reference implementation from which a specification can be derived.
I like to do the bottom-up approach of first writing code and the writing a specification that matches the code and all the pitfalls that were encountered writing it.
What kind-of works:
There are lots of bugs still. Sometimes the value parser seems to miss forfeits. Sometimes I get bugs when starting up. It is all in a state of flux. I am publishing this PR early as @HostFat and some others were curious about this. That said, I tried to clean up my code as much as possible and separate it into a series of clean commits.
BIG FAT WARNING: This code is by no means production ready!! If you want to try it out, use test net or create a wallet with some miniscule amount of BCH in it. Losing money is still likely.
EDIT: For those curious to try this out, here's a walk through the functionality with pictures: https://github.com/awemany/electron-cash-zcf-demo/blob/master/README.md