diff --git a/blockchain/merkle.go b/blockchain/merkle.go index 5d7e6367..11edfc5f 100644 --- a/blockchain/merkle.go +++ b/blockchain/merkle.go @@ -34,11 +34,8 @@ func HashMerkleBranches(left *wire.ShaHash, right *wire.ShaHash) *wire.ShaHash { copy(sha[:wire.HashSize], left[:]) copy(sha[wire.HashSize:], right[:]) - // Create a new sha hash from the double sha 256. Ignore the error - // here since SetBytes can't fail here due to the fact DoubleSha256 - // always returns a []byte of the right size regardless of input. - newSha, _ := wire.NewShaHash(wire.DoubleSha256(sha[:])) - return newSha + newSha := wire.DoubleSha256SH(sha[:]) + return &newSha } // BuildMerkleTreeStore creates a merkle tree from a slice of transactions, diff --git a/wire/bench_test.go b/wire/bench_test.go index b7d2b7d5..01b29538 100644 --- a/wire/bench_test.go +++ b/wire/bench_test.go @@ -394,7 +394,7 @@ func BenchmarkTxSha(b *testing.B) { } // BenchmarkDoubleSha256 performs a benchmark on how long it takes to perform a -// double sha 256. +// double sha 256 returning a byte slice. func BenchmarkDoubleSha256(b *testing.B) { b.StopTimer() var buf bytes.Buffer @@ -409,3 +409,20 @@ func BenchmarkDoubleSha256(b *testing.B) { _ = DoubleSha256(txBytes) } } + +// BenchmarkDoubleSha256SH performs a benchmark on how long it takes to perform +// a double sha 256 returning a ShaHash. +func BenchmarkDoubleSha256SH(b *testing.B) { + b.StopTimer() + var buf bytes.Buffer + if err := genesisCoinbaseTx.Serialize(&buf); err != nil { + b.Errorf("Serialize: unexpected error: %v", err) + return + } + txBytes := buf.Bytes() + b.StartTimer() + + for i := 0; i < b.N; i++ { + _ = DoubleSha256SH(txBytes) + } +} diff --git a/wire/blockheader.go b/wire/blockheader.go index 3ca8619c..99e1eeb9 100644 --- a/wire/blockheader.go +++ b/wire/blockheader.go @@ -46,21 +46,17 @@ const blockHeaderLen = 80 // BlockSha computes the block identifier hash for the given block header. func (h *BlockHeader) BlockSha() (ShaHash, error) { - // Encode the header and run double sha256 everything prior to the - // number of transactions. Ignore the error returns since there is no - // way the encode could fail except being out of memory which would - // cause a run-time panic. Also, SetBytes can't fail here due to the - // fact DoubleSha256 always returns a []byte of the right size - // regardless of input. + // Encode the header and double sha256 everything prior to the number of + // transactions. Ignore the error returns since there is no way the + // encode could fail except being out of memory which would cause a + // run-time panic. var buf bytes.Buffer - var sha ShaHash _ = writeBlockHeader(&buf, 0, h) - _ = sha.SetBytes(DoubleSha256(buf.Bytes()[0:blockHeaderLen])) // Even though this function can't currently fail, it still returns // a potential error to help future proof the API should a failure // become possible. - return sha, nil + return DoubleSha256SH(buf.Bytes()), nil } // Deserialize decodes a block header from r into the receiver using a format diff --git a/wire/common.go b/wire/common.go index 27264951..48251e2f 100644 --- a/wire/common.go +++ b/wire/common.go @@ -526,3 +526,10 @@ func DoubleSha256(b []byte) []byte { second := fastsha256.Sum256(first[:]) return second[:] } + +// DoubleSha256SH calculates sha256(sha256(b)) and returns the resulting bytes +// as a ShaHash. +func DoubleSha256SH(b []byte) ShaHash { + first := fastsha256.Sum256(b) + return ShaHash(fastsha256.Sum256(first[:])) +} diff --git a/wire/msgtx.go b/wire/msgtx.go index fa262e33..f24ae098 100644 --- a/wire/msgtx.go +++ b/wire/msgtx.go @@ -170,18 +170,14 @@ func (msg *MsgTx) TxSha() (ShaHash, error) { // Encode the transaction and calculate double sha256 on the result. // Ignore the error returns since the only way the encode could fail // is being out of memory or due to nil pointers, both of which would - // cause a run-time panic. Also, SetBytes can't fail here due to the - // fact DoubleSha256 always returns a []byte of the right size - // regardless of input. + // cause a run-time panic. buf := bytes.NewBuffer(make([]byte, 0, msg.SerializeSize())) _ = msg.Serialize(buf) - var sha ShaHash - _ = sha.SetBytes(DoubleSha256(buf.Bytes())) // Even though this function can't currently fail, it still returns // a potential error to help future proof the API should a failure // become possible. - return sha, nil + return DoubleSha256SH(buf.Bytes()), nil } // Copy creates a deep copy of a transaction so that the original does not get