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

Implement BIP-143-like sighash #1598

Merged
merged 33 commits into from
Mar 17, 2021
Merged

Conversation

svarogg
Copy link
Collaborator

@svarogg svarogg commented Mar 11, 2021

@svarogg svarogg linked an issue Mar 11, 2021 that may be closed by this pull request
@codecov
Copy link

codecov bot commented Mar 11, 2021

Codecov Report

Merging #1598 (8010e9d) into v0.10.0-dev (caf251b) will decrease coverage by 0.02%.
The diff coverage is 81.81%.

❗ Current head 8010e9d differs from pull request most recent head bf4a242. Consider uploading reports for the commit bf4a242 to get more accurate results
Impacted file tree graph

@@               Coverage Diff               @@
##           v0.10.0-dev    #1598      +/-   ##
===============================================
- Coverage        60.01%   59.98%   -0.03%     
===============================================
  Files              515      516       +1     
  Lines            20454    20494      +40     
===============================================
+ Hits             12275    12293      +18     
- Misses            6229     6247      +18     
- Partials          1950     1954       +4     
Impacted Files Coverage Δ
cmd/wallet/send.go 0.00% <0.00%> (ø)
domain/consensus/utils/txscript/error.go 88.88% <ø> (ø)
domain/consensus/utils/txscript/script.go 70.80% <ø> (-8.04%) ⬇️
domain/consensus/utils/txscript/standard.go 58.38% <0.00%> (ø)
domain/consensus/utils/txscript/opcode.go 87.89% <37.50%> (-0.32%) ⬇️
domain/consensus/utils/serialization/common.go 40.27% <53.84%> (+5.92%) ⬆️
...utils/consensushashing/calculate_signature_hash.go 91.46% <91.46%> (ø)
domain/consensus/model/externalapi/hash.go 85.71% <100.00%> (+0.42%) ⬆️
...ses/transactionvalidator/transaction_in_context.go 68.98% <100.00%> (ø)
domain/consensus/utils/txscript/engine.go 85.92% <100.00%> (-0.77%) ⬇️
... and 8 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update caf251b...bf4a242. Read the comment docs.

address.EncodeAddress(): key,
}), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): scriptPubKey.Script,
})); err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please reformat the above five lines for readability's sake.

const (
SigHashAll SigHashType = 0x1
SigHashNone SigHashType = 0x2
SigHashSingle SigHashType = 0x3
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it'll be a tiny bit more clear that this is a bit field if you write it as 0x01.

Copy link
Member

Choose a reason for hiding this comment

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

we could even go full literal: 0b00000001 which makes it easier to see the bits and masks with the naked eye (ie SigHashMask = 0x1f becomes: 0b00011111)

}
hashWriter := hashes.NewTransactionSigningHashWriter()
hashTxOut(hashWriter, tx.Outputs[inputIndex])
return hashWriter.Finalize()
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think you should update reusedValues.outputsHash here and only return later.

Copy link
Member

Choose a reason for hiding this comment

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

this outputsHash isn't cached, because if it's single then each input will have its own outputsHash, you can't cache them between inputs

Copy link
Collaborator

@stasatdaglabs stasatdaglabs left a comment

Choose a reason for hiding this comment

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

.

domain/consensus/utils/serialization/common.go Outdated Show resolved Hide resolved
Comment on lines +138 to +140
if hashType.isSigHashNone() {
return externalapi.NewZeroHash()
}
Copy link
Member

Choose a reason for hiding this comment

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

I think there's a meaningful difference between this and the bitcoin approach.
the difference is how do we handle unknown sighashes, in bitcoin unknown hash types will be all zeros here, and in this code SigHashAll will be the default.
I'm not sure which is better and what kinds of validation happen to the sighash before this function (maybe only valid known sighashes can enter this function)

Copy link
Member

Choose a reason for hiding this comment

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

Same for getSequencesHash

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've added a validation in the beggining of CalculateSignatureHash that makes sure that the SigHashType passed is a standard one, so we are not going to have a default (it will error out if you pass 0)

domain/consensus/utils/txscript/engine.go Outdated Show resolved Hide resolved
domain/consensus/utils/txscript/engine.go Outdated Show resolved Hide resolved
@svarogg svarogg changed the title Implement BIP143-like sighash Implement BIP-143-like sighash Mar 16, 2021
}), mkGetScript(nil), nil); err != nil {
if err := signAndCheck(msg, tx, i, scriptPubKey, hashType, mkGetKey(map[string]*secp256k1.SchnorrKeyPair{
address.EncodeAddress(): key,
}), mkGetScript(nil)); err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please reformat these three lines as well.

stasatdaglabs
stasatdaglabs previously approved these changes Mar 16, 2021
SigHashAnyOneCanPay SigHashType = 0x80
SigHashAll SigHashType = 0b00000001
SigHashNone SigHashType = 0b00000010
SigHashSingle SigHashType = 0b00000100
Copy link
Member

Choose a reason for hiding this comment

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

That's 4, it should be 3

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is deliberate.
@stasatdaglabs asked me to do this so that SigHashType is a true bitfield.

LMK if you disagree

Comment on lines 27 to 36
func (sht SigHashType) isStandardSigHashType() bool {
switch sht {
case SigHashAll, SigHashNone, SigHashSingle,
SigHashAll | SigHashAnyOneCanPay, SigHashNone | SigHashAnyOneCanPay, SigHashSingle | SigHashAnyOneCanPay:
return true
default:
return false
}
}

Copy link
Member

Choose a reason for hiding this comment

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

Are we sure this is good and correct?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

As sure as one can be.
Many things inside the code and tests of CalculateSignatureHash assume the above is correct.
If it is not - we should fix both it and the code.

hashType: 0x04,
hashType: 0b00000011,
Copy link
Member

Choose a reason for hiding this comment

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

you meant 0b00000100?

@stasatdaglabs stasatdaglabs merged commit cebcab7 into v0.10.0-dev Mar 17, 2021
@stasatdaglabs stasatdaglabs deleted the 1341-bip-143-sighash branch March 17, 2021 13:17
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.

Replace sighash algorithm with BIP143 sighash
3 participants