Skip to content

Conversation

NicolasDorier
Copy link
Contributor

This PR makes it possible to call FundRawTransaction with pre filled inputs not belonging to the wallet.
This is very useful for AnyOneCanPay scenario, where one of a third party only cover part of a transaction.

The necessary information to complete the transaction is taken from of the mempool and coinview.

A typical example would involves Alice and Bob wanting to fund 0.5 each to the payment channel. Alice would give her input, and Bob would be able to complete the missing amount via FundRawTransaction.

A follow up PR will allow the client fundrawtransaction to pass previous TxOuts corresponding to the inputs. This is necessary for filling transaction in some 2nd layer protocols, where the the inputs's of the transaction to fund have not yet been broadcasted.

This supersede my previous attempt at #10068 which I closed, as it was harder to review.

The first two commits are strict refactoring.
The third is the one checking information in the coinview.
Rest is about tests.

Copy link
Contributor

@TheBlueMatt TheBlueMatt left a comment

Choose a reason for hiding this comment

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

Concept ACK.

Its really quite unfortunate we cant properly calculate fee when using most outputs here. Maybe its possible to assume, at a minimum, a compressed pubkey and standard signature size for "normal" things like P2PH? Alternatively, could force the user to provide some additional data, like a set of pubkeys needed.

Also, Windows line endings in a few commits :p

setPresetCoins.insert(CInputCoin(pcoin, outpoint.n));
} else
return false; // TODO: Allow non-wallet inputs
auto foundCoin = coinControl->FindKnownCoin(outpoint);
Copy link
Contributor

Choose a reason for hiding this comment

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

Wont this break Qt coin control as-is? I believe it either needs a similar AddKnownCoins call or the old code needs to remain and just get a second option.

@NicolasDorier
Copy link
Contributor Author

Fixed the end-of-line and fixed wallet.cpp to not break QT coin control as suggested by @TheBlueMatt .
In a follow up PR I will clean QT coin control dialog to use AddKnownCoin. I briefly tried to do that, it simplified quite a lot. I prefer keeping it in another PR though.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can we avoid boost::optional?
Maybe std::shared_ptr<CInputCoin> should do it?
Maybe switch the map keys to std::pair<uint256, int>?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

why? We are already using boost::optional from https://github.com/bitcoin/bitcoin/pull/10165/files#diff-b2bb174788c7409b671c46ccc86034bdR2088 . This will be implemented in std:: in C++0x17 as well. I was kind of against it on #10165, but it turns out to be very handy.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Another solution is

bool FindKnownCoin(coinst COutPoint&, CInputCoin& output)

Copy link
Contributor

Choose a reason for hiding this comment

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

Why not use setSelected (and maybe extend/migrate it to fit your use-case), AFAIK they serve the same purpose (selecting an desired input over the GUI).

I think this is not something we should fix in a follow-up PR because it kinda messes up the design.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I briefly tried, but it changes lot's of stuff in the QT Code. I prefer doing it in a separate PR, as I fear the changes will be too hard to review.

The design of this PR will not be greatly impacted once I switch setSelected to use CInputCoin everywhere. Basically only this block https://github.com/bitcoin/bitcoin/pull/10202/files#diff-b2bb174788c7409b671c46ccc86034bdR2247 will need to be removed.

@jonasschnelli
Copy link
Contributor

Concept ACK.
I think we should not have two code parts for handling pre-selected-inputs and I think we should avoid using boost::optional (if reasonable possible).

@kanzure
Copy link
Contributor

kanzure commented May 12, 2017

Its really quite unfortunate we cant properly calculate fee when using most outputs here. Maybe its possible to assume, at a minimum, a compressed pubkey and standard signature size for "normal" things like P2PH? Alternatively, could force the user to provide some additional data, like a set of pubkeys needed.

How about user gives an estimated final transaction size (minus whatever fundrawtransaction adds) when calling fundrawtransaction? Then ignore all "unsolvable" inputs or whatever.

Alternatively, what about allowing fundrawtransaction feeRate to be 0 even for "unsolvable" inputs etc in the transaction, and user sets another parameter like ignoreFee--- because perhaps the user has arranged for fee to come from somewhere else, or maybe the user plans to delete one of the outputs to convert the output to fee.

For my particular problem (discussed in IRC) I believe the following workaround makes sense: createrawtransaction with a change output set to the final fee value that I would like, fundrawtransaction with a reasonable feeRate set, then using the fee value in the fundrawtransaction output dictionary it is easy to switch the change output from my original "fee" to the new fee (important to account for difference or else funds could be lost here). This would move any extra fee from "fundrawtransaction" to the change output, and my original change output "fee" has now become the real fee.

@NicolasDorier
Copy link
Contributor Author

@kanzure I think nothing has to be done to calculate fee correctly. Currently, the user can just fill dummy input of the right size into the scriptSig, this would correctly evaluate the fees.

@NicolasDorier
Copy link
Contributor Author

NicolasDorier commented May 17, 2017

I rebased, and rewrote this part https://github.com/bitcoin/bitcoin/pull/10202/files#diff-b2bb174788c7409b671c46ccc86034bdL2259 to be more diff friendly so you can see it is trivially right.

@NicolasDorier
Copy link
Contributor Author

@jonasschnelli I did not managed to find good alternative to boost::optional. I tried bool FindKnownCoin(coinst COutPoint&, CInputCoin& output) but since CInputCoin can't be in uninitialized state, it does not work.

I don't think it is such a big deal, we use boost::optional elsewhere and std::optional will eventually exist.

@jonasschnelli
Copy link
Contributor

Needs rebase.

@NicolasDorier
Copy link
Contributor Author

I workedaround this need for this.

@domob1812
Copy link
Contributor

This would indeed be very useful. Was there a particular reason for closing this, or was it simply closed because it was no longer needed for you? Would it make sense for me to take up the patch, rebase it and resubmit? Or are there any technical objections to the code / approach itself?

@NicolasDorier
Copy link
Contributor Author

@domob1812 I closed it because for my projects I decided to stop using RPC's wallet API completely, and did my own wallet. It was the fastest way to reach my goal, so I did not wanted to spend time rebasing this over and over. Feel free to clone this PR and take care of it.

@domob1812
Copy link
Contributor

@NicolasDorier: Thanks for the answer, that makes sense. I also have other, more important things to work on for now, but then I'll consider taking over this PR when I run into the need to do this on my own projects.

@JeremyRand
Copy link
Contributor

Am I correct in inferring that if #17211 gets merged, that would eliminate the need for this PR? Or does this PR do something that that PR doesn't do?

@bitcoin bitcoin locked and limited conversation to collaborators Oct 30, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants