github.com/amazechain/amc@v0.1.3/internal/hashing.go (about) 1 // Copyright 2023 The AmazeChain Authors 2 // This file is part of the AmazeChain library. 3 // 4 // The AmazeChain library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The AmazeChain library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the AmazeChain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package internal 18 19 import ( 20 "bytes" 21 "github.com/amazechain/amc/common/crypto" 22 "github.com/amazechain/amc/common/types" 23 "github.com/amazechain/amc/utils" 24 "sync" 25 26 "golang.org/x/crypto/sha3" 27 ) 28 29 // hasherPool holds LegacyKeccak256 hashers for rlpHash. 30 var hasherPool = sync.Pool{ 31 New: func() interface{} { return sha3.NewLegacyKeccak256() }, 32 } 33 34 // encodeBufferPool holds temporary encoder buffers for DeriveSha and TX encoding. 35 var encodeBufferPool = sync.Pool{ 36 New: func() interface{} { return new(bytes.Buffer) }, 37 } 38 39 // DerivableList is the input to DeriveSha. 40 // It is implemented by the 'Transactions' and 'Receipts' types. 41 // This is internal, do not use these methods. 42 type DerivableList interface { 43 Len() int 44 EncodeIndex(int, *bytes.Buffer) 45 } 46 47 func encodeForDerive(list DerivableList, i int, buf *bytes.Buffer) []byte { 48 buf.Reset() 49 list.EncodeIndex(i, buf) 50 // It's really unfortunate that we need to do perform this copy. 51 // StackTrie holds onto the values until Hash is called, so the values 52 // written to it must not alias. 53 return utils.Copy(buf.Bytes()) 54 } 55 56 // DeriveSha creates the tree hashes of transactions and receipts in a block header. 57 func DeriveSha(list DerivableList) (h types.Hash) { 58 59 sha := hasherPool.Get().(crypto.KeccakState) 60 defer hasherPool.Put(sha) 61 sha.Reset() 62 63 valueBuf := encodeBufferPool.Get().(*bytes.Buffer) 64 defer encodeBufferPool.Put(valueBuf) 65 66 for i := 0; i < list.Len(); i++ { 67 value := encodeForDerive(list, i, valueBuf) 68 sha.Write(value) 69 } 70 sha.Read(h[:]) 71 return h 72 }