core: types: less allocations when hashing and tx handling (#21265)

* core, crypto: various allocation savings regarding tx handling

* core: reduce allocs for gas price comparison

This change reduces the allocations needed for comparing different transactions to each other.
A call to `tx.GasPrice()` copies the gas price as it has to be safe against modifications and
also needs to be threadsafe. For comparing and ordering different transactions we don't need
these guarantees

* core: added tx.GasPriceIntCmp for comparison without allocation

adds a method to remove unneeded allocation in comparison to tx.gasPrice

* core/types: pool legacykeccak256 objects in rlpHash

rlpHash is by far the most used function in core that allocates a legacyKeccak256 object on each call.
Since it is so widely used it makes sense to add pooling here so we relieve the GC.
On my machine these changes result in > 100 MILLION less allocations and > 30 GB less allocated memory.

* reverted some changes

* reverted some changes

* trie: use crypto.KeccakState instead of replicating code

Co-authored-by: Martin Holst Swende <martin@swende.se>
This commit is contained in:
Marius van der Wijden
2020-06-30 11:59:06 +02:00
committed by GitHub
parent e376d2fb31
commit ddeea1e0c6
9 changed files with 72 additions and 32 deletions

View File

@ -24,6 +24,7 @@ import (
"encoding/hex"
"errors"
"fmt"
"hash"
"io"
"io/ioutil"
"math/big"
@ -51,23 +52,33 @@ var (
var errInvalidPubkey = errors.New("invalid secp256k1 public key")
// KeccakState wraps sha3.state. In addition to the usual hash methods, it also supports
// Read to get a variable amount of data from the hash state. Read is faster than Sum
// because it doesn't copy the internal state, but also modifies the internal state.
type KeccakState interface {
hash.Hash
Read([]byte) (int, error)
}
// Keccak256 calculates and returns the Keccak256 hash of the input data.
func Keccak256(data ...[]byte) []byte {
d := sha3.NewLegacyKeccak256()
b := make([]byte, 32)
d := sha3.NewLegacyKeccak256().(KeccakState)
for _, b := range data {
d.Write(b)
}
return d.Sum(nil)
d.Read(b)
return b
}
// Keccak256Hash calculates and returns the Keccak256 hash of the input data,
// converting it to an internal Hash data structure.
func Keccak256Hash(data ...[]byte) (h common.Hash) {
d := sha3.NewLegacyKeccak256()
d := sha3.NewLegacyKeccak256().(KeccakState)
for _, b := range data {
d.Write(b)
}
d.Sum(h[:0])
d.Read(h[:])
return h
}