-
Notifications
You must be signed in to change notification settings - Fork 400
PSBT for Confidential Assets #600
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
Conversation
|
could you rebase? |
instagibbs
left a comment
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.
concept ACK, first look seems good.
| } | ||
|
|
||
| CAmount CWalletTx::GetOutputValueOut(unsigned int output_index) const { | ||
| void CWalletTx::GetNonIssuanceBlindingData(const unsigned int output_index, CPubKey* blinding_pubkey_out, CAmount* value_out, uint256* value_factor_out, CAsset* asset_out, uint256* asset_factor_out) const { |
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.
this refactoring could be its own commit
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.
done
src/wallet/wallet.cpp
Outdated
| // One change script per output asset. | ||
| size_t index = 0; | ||
| for (const std::pair<CAsset, CAmount>& value : mapValue) { | ||
| for (const std::pair<const CAsset, CAmount>& value : mapValue) { |
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.
compiler complaint squashing could be its own commit
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 think this must have gone away in the rebase
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 yeah
|
|
||
| CMutableTransaction tx_tmp = tx; // We don't want to mutate the transaction in the PSBT yet, just extract blinding data | ||
|
|
||
| // TODO(gwillen): Make this do something better than fail silently if there are any issuances, reissuances, pegins, etc. |
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.
PSBTs can't really encode these anyways yet, I think we're safe for now.
Supporting the creation of issuance/peg-in inputs in a PSBT format is the harder part.
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.
Well, the PSBT can encode anything the CTransaction can encode, so I can make a PSBT of an issuance -- I just can't blind it. (Perhaps I also can't sign it -- I didn't try a fully unblinded one.)
| o.range_proof = tx_tmp.witness.vtxoutwit[i].vchRangeproof; | ||
| o.surjection_proof = tx_tmp.witness.vtxoutwit[i].vchSurjectionproof; | ||
|
|
||
| o.blinding_pubkey = CPubKey(); // Once we're done blinding, remove the pubkeys to signal that it's complete |
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 guess this makes sense. We remove partial sigs once a full sig is complete right?
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.
Yes, and I suspect that there's more pruning I could do with the goal of keeping the PSBTs small (which I expect is why we do that), but this specific removal is actually important as a signal to signpsbt that it's okay to sign. (Since the hack with the nonce field is gone in this flow.)
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.
why wouldn't the presence of the other fields show that?
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.
The only way to tell that an output is intended to be blinded is that it has a pubkey. Absence of blinders could mean "not going to be blinded" or "hasn't been blinded yet".
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.
So I guess you could indeed check for "has a pubkey and blinders" or "has no pubkey", but just checking for not having a pubkey seems easier (and is similar to what the code was doing before). But I can go either way as you like.
|
|
||
| CMutableTransaction& tx = *psbtx.tx; | ||
|
|
||
| // TODO(gwillen): Replace all this with the 'bonus output' scheme to use an OP_RETURN to balance blinders, with a rangeproof exponent of -1 (public). |
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.
with known blinding pubkey, right?
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 believe the scheme we talked about -- which I don't expect to fully understand before implementing it -- was to just make up a random pubkey and then throw it away after, because nobody ever needs to be able to rewind these outputs.
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.
that works too. Could just be the generator point G or something stupid as well.
|
Rebased, still need to split things up a bit. Also looks like I killed CI with the rebase, will investigate. EDIT: nevermind, of course CI fails -- the tests don't pass with all the extra printfs in there. That will go away on its own when I remove those. |
d7a44e5 to
2921cb4
Compare
|
apparently somehow I lost the compiler warning squashing in the rebase, but not because it was fixed upstream? So I added it back as its own commit. Also fixed tests by removing all the stray printfs, none of them appeared worthy of upgrading to LogPrintf. I think this should be ready for a real review. |
|
fixed travis complaints (coming from lints that don't run on my system because they have some python dependency I can't get to install.) |
|
Linters are hard to replicate locally for me as well. Thanks.
…On Thu, May 2, 2019, 9:42 PM gwillen ***@***.***> wrote:
fixed travis complaints (coming from lints that don't run on my system
because they have some python dependency I can't get to install.)
—
You are receiving this because your review was requested.
Reply to this email directly, view it on GitHub
<#600 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABMAFU2D27IOK5VJPQOZAB3PTOJ7PANCNFSM4HJSS4DA>
.
|
|
ok looks like everything but bitcoin compatibility test for psbt is working: see: |
|
Hm, interesting. It only fails on a single platform, which makes me worry it's nondeterministic. Also, I didn't realize those compatibility tests existed, so I wasn't running them -- I will try and see what it does locally. ALSO, I think I'm still waiting for you to help me figure out where to condition on g_con_elementsmode. So assuming the compatibility tests run without that, that may fix it? |
|
@instagibbs formal reminder that I am waiting for your review on this (and guidance on where to put g_con_elementsmode checks) |
|
@stevenroose promised a review Soon(TM), I think after his next catchup PR. |
|
@stevenroose @instagibbs piiiing? :-) I would really like to get this cleaned up and in. I definitely still need help sorting out what g_con_elementsmode is for, and where it should fit in (to make the bitcoin backwards-compat tests pass, which still fail at present.) |
|
please add tests for |
|
Ok so, belated comment on your last comment @instagibbs -- there already were tests for walletcreatefundedpsbt, but nothing is actually testing that things that should be blinded are, and nothing is testing that nonces don't show up where they shouldn't. I have fixed walletcreatefundedpsbt and converttopsbt, and tested by hand, and the tests pass; but I haven't gone back and made the tests check that expected blinding is actually happening. I expect that the code itself should be done at this point, though -- can you take another look? |
src/rpc/rawtransaction.cpp
Outdated
| "blindpsbt \"psbt\" ( ignoreblindfail )\n" | ||
| "\nUse the blinding data from the PSBT inputs to generate the blinding data for the PSBT outputs.\n" | ||
| "\nUse the blinding data from the PSBT inputs to generate the blinding data for the PSBT outputs.\n\n" | ||
| "TODO: Not expected to work on issuance/reissuance/peg transactions yet.\n" |
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'd rather not have a TODO in help text :) Just telling the user it isn't supported is enough
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 fair. Fixing.
| // At this point, if the nonce field is present it should be a smuggled | ||
| // pubkey, and not a real nonce. Convert it back to a pubkey and strip | ||
| // it out. | ||
| psbtx.outputs[i].blinding_pubkey = CPubKey(tx.vout[i].nNonce.vchCommitment); |
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.
do we want to sanity check it's a IsFullyValid key?
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.
Leaving this per discussion.
src/wallet/rpcwallet.cpp
Outdated
| // If we're signing, check that the transaction is not still in need of blinding | ||
| if (sign) { | ||
| for (const PSBTOutput& o : psbtx.outputs) { | ||
| if (o.blinding_pubkey.IsValid()) { |
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 usually prefer IsFullyValid()
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.
Leaving this per discussion.
test/functional/rpc_psbt.py
Outdated
| import json | ||
| import os | ||
|
|
||
| import IPython |
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.
que?
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.
whoop lol
was using this for debugging. Removed.
|
Addressed comments, still have to debug the issue I uncovered with the walletcreatefundedpsbt change output coming out improperly unblinded. |
|
Sigh, ok, gave up on doing createfundedpsbt in (what I felt was) the nice way. The mystery of FundTransaction runs way too deep. Instead, I let FundTransaction do its thing, then extract the pubkeys from the nonces afterwards. Still need to rebase on 0.18. |
|
@gwillen right, seems to be the least painful thing to do. We let Core-ish stuff alone if it makes rebasing upstream easier. |
|
@instagibbs Heh... I didn't even think about the ease-of-rebase issue. ^^; I am still working on the rebase onto 0.18. Currently the rpc_psbt.py test is erroring out immediately at the top of the very first test with "insufficient funds", which confuses me and I'm not sure what's up. |
5becc1e to
c4f3605
Compare
|
Rebased onto master. After a bunch of fixups, the errors left from Travis are (1) an apparent memory-exhaustion running tsan, and (2) a timeout. Not sure what's the best way to deal with those but they're not obviously something I can fix. |
|
Sounds like the builds we haven't been able to get working from upstream.
Will take a look Monday!
…On Fri, Jul 26, 2019, 11:21 PM Glenn Willen ***@***.***> wrote:
Rebased onto master.
After a bunch of fixups, the errors left from Travis are (1) an apparent
memory-exhaustion running tsan, and (2) a timeout. Not sure what's the best
way to deal with those but they're not obviously something I can fix.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#600?email_source=notifications&email_token=ABMAFU2AXMAU4OFJHVEBQB3QBO5NJA5CNFSM4HJSS4DKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD26CQKQ#issuecomment-515647530>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABMAFU3IIXQMRPRUBWZZO4TQBO5NJANCNFSM4HJSS4DA>
.
|
|
Please update the OP to list some of the common usage sequences for RPC. Also an explicit list of the new fields in the description is probably apt. |
|
oh could you also say what the PR isn't doing in the OP text? e.g., doesn't handle issuance/peg-ins. |
|
Updated the PR description. |
|
Addressed all comments. PTAL? |
|
Changes look good, one more linter: |
|
Lol, it's really hard for me to not type semicolons at the end of lines. I blame C/C++ for this. Fixed. (One day I will get the python lints working on OS X.) |
|
Added a sentence of explanation of output_pubkeys_out in ConstructTransaction. I did leave it in because there's still once place I did use it. |
|
Squashed down to a few sensible commits. |
|
ACK |
|
Thanks @instagibbs! Been a long road for this one. |
|
appreciate the heavy lifting! |
|
|
||
| // How many are we trying to blind? | ||
| int num_pubkeys = 0; | ||
| unsigned int keyIndex = -1; |
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.
Flagged by ubsan for being an implicit signedness conversion (which is not UB but ubsan lints for it). But also this is literally UB because keyIndex is never checked against this -1 value, it's just used as an array index.
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.
Should be fixed by #900, just noting here for posterity.
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.
Oh, this block appears to have been copied from rawblindrawtransaction which has had this issue since at least #515
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.
Oh, my bad, in both cases it is actually safe becasue keyIndex is only -1 if num_pubkeys is left at 0, and keyIndex is only used as an index when num_pubkeys is nonzero.
This PR extends the PSBT format and RPCs to handle Confidential Assets transactions.
New fields in PSBT inputs: Unblinded value, Value blinder, Unblinded asset, Asset blinder.
New fields in PSBT outputs: Recipient blinding pubkey, Value commitment, Value blinder, Asset commitment, Asset blinder, Nonce commitment, Range proof, Surjection proof.
We preserve the existing invariant that the unsigned transaction inside a PSBT never changes during the process; all updates that need to be applied to produce the final signed transaction are accumulated in the PSBT fields listed above.
The process is as follows:
converttopsbt[deprecated],walletcreatefundedpsbt,createpsbtwalletfillpsbtdata.walletprocesspsbtRPC [deprecated], which tried to both fill and sign the PSBT (which is not workable in the Confidential Assets setting.)blindpsbt.blindpsbtis called.walletsignpsbt. As with updating, this can be done by multiple wallets as necessary for the inputs being signed.finalizepsbtis used to create the final transaction in the regular transaction format, as before.sendrawtransactionis used, which will check to make sure that blinding was performed properly before sending.