Skip to content
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

Try both TX serialization formats in createrawtransaction #1502

Conversation

torkelrogstad
Copy link
Contributor

Currently, it is not possible to use the rpcclient package to create a raw TX with Bitcoin Core if the transaction you're creating has no inputs. This is a realistic scenario, as you would typically call createrawtransaction with your outputs specified, and then follow up with fundrawtransaction.

The reason the RPC call fails is that we assume the returned transaction is encoded with the new witness format that was introduced with Segwit. We solve this by simply trying both serialization formats. If its possible to detect which format is used (so we avoid doing it twice) I'll update the PR.

@octobocto
Copy link

LGTM, but maybe leave a comment for context? Just a short version of what you commented here would be nice, for example we try both serialization formats, to be able to create a transaction with no inputs

@jakesylvestre
Copy link
Collaborator

Tbh, @bjornoj I think the existing comment is clear enough, not sure we need anything more verbose

Comment on lines -237 to +242
return nil, err
// we try both the new and old encoding format
witnessErr := msgTx.Deserialize(bytes.NewReader(serializedTx))
if witnessErr != nil {
legacyErr := msgTx.DeserializeNoWitness(bytes.NewReader(serializedTx))
if legacyErr != nil {
return nil, legacyErr
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

If both return an error, would the call to msgTx.Deserialize(...) return something useful that isn't already covered by msgTx.DeserializeNoWitness(...)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, I'm not sure I understand what you mean. Is this about which error to return?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sort of, yeah. Although I also just looked at the code and it's fine to do it this way. Let's say both msgTx.Deserialize and msgTx.DeserializeNoWitness both return an error. In this case, we go down the if witnessErr != nil branch and eventually return (nil, legacyErr). But there is a witnessErr which is non-nil and I was wondering if it might make sense to return both error messages.
I just checked the code though and both just make calls to msg.BtcDecode so it should be fine.

@jakesylvestre
Copy link
Collaborator

@jcvernaleo (as per #1530)

  • high priority
  • bug (technically an enhancement, but a clear compatibility issue with bitcoind rpc)

This has been pretty closely reviewed/run locally by myself and @Rjected so probably mergable

rpcclient/rawtransactions.go Outdated Show resolved Hide resolved
@torkelrogstad torkelrogstad force-pushed the 2019-12-02-createrawtransaction-receive-btcd branch from 632b815 to 302717b Compare March 27, 2020 10:17
Copy link
Member

@jcvernaleo jcvernaleo left a comment

Choose a reason for hiding this comment

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

OK

@jcvernaleo jcvernaleo merged commit 57d44d0 into btcsuite:master Mar 27, 2020
@Rjected Rjected mentioned this pull request May 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants