Compare commits

..

8 Commits

Author SHA1 Message Date
VM
d572c77e4c fix: fillTransactions func add time metrics 2024-05-29 15:46:25 +08:00
will@2012
565085959b perf: add more layer tree metrics 2024-05-28 20:43:42 +08:00
will@2012
b7b1b0c001 fix: add temp debug code 2024-05-28 18:52:02 +08:00
will@2012
08702d3380 perf: disable tx indexer 2024-05-21 15:37:20 +08:00
will@2012
91e3a3ea1f perf: add more log 2024-05-20 23:02:40 +08:00
will@2012
73477bd0fc perf: enable tx indexer 2024-05-20 21:10:14 +08:00
will@2012
8749c8e8ce perf: add more metrics/log to perf pebble 2024-05-20 20:40:51 +08:00
will@2012
79fe2899c7 chore: add more metrics to perf pbss 2024-05-20 17:35:29 +08:00
35 changed files with 235 additions and 5708 deletions

View File

@@ -1,15 +1,4 @@
# Changelog # Changelog
## v1.4.8
### FEATURE
* [\#2483](https://github.com/bnb-chain/bsc/pull/2483) core/vm: add secp256r1 into PrecompiledContractsHaber
* [\#2400](https://github.com/bnb-chain/bsc/pull/2400) RIP-7212: Precompile for secp256r1 Curve Support
### IMPROVEMENT
NA
### BUGFIX
NA
## v1.4.7 ## v1.4.7
### FEATURE ### FEATURE
* [\#2439](https://github.com/bnb-chain/bsc/pull/2439) config: setup Mainnet Tycho(Cancun) hardfork date * [\#2439](https://github.com/bnb-chain/bsc/pull/2439) config: setup Mainnet Tycho(Cancun) hardfork date

View File

@@ -63,7 +63,6 @@ var (
Flags: flags.Merge([]cli.Flag{ Flags: flags.Merge([]cli.Flag{
utils.CachePreimagesFlag, utils.CachePreimagesFlag,
utils.OverrideCancun, utils.OverrideCancun,
utils.OverrideHaber,
utils.OverrideVerkle, utils.OverrideVerkle,
}, utils.DatabaseFlags), }, utils.DatabaseFlags),
Description: ` Description: `
@@ -257,10 +256,6 @@ func initGenesis(ctx *cli.Context) error {
v := ctx.Uint64(utils.OverrideCancun.Name) v := ctx.Uint64(utils.OverrideCancun.Name)
overrides.OverrideCancun = &v overrides.OverrideCancun = &v
} }
if ctx.IsSet(utils.OverrideHaber.Name) {
v := ctx.Uint64(utils.OverrideHaber.Name)
overrides.OverrideHaber = &v
}
if ctx.IsSet(utils.OverrideVerkle.Name) { if ctx.IsSet(utils.OverrideVerkle.Name) {
v := ctx.Uint64(utils.OverrideVerkle.Name) v := ctx.Uint64(utils.OverrideVerkle.Name)
overrides.OverrideVerkle = &v overrides.OverrideVerkle = &v

View File

@@ -189,10 +189,6 @@ func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) {
v := ctx.Uint64(utils.OverrideCancun.Name) v := ctx.Uint64(utils.OverrideCancun.Name)
cfg.Eth.OverrideCancun = &v cfg.Eth.OverrideCancun = &v
} }
if ctx.IsSet(utils.OverrideHaber.Name) {
v := ctx.Uint64(utils.OverrideHaber.Name)
cfg.Eth.OverrideHaber = &v
}
if ctx.IsSet(utils.OverrideVerkle.Name) { if ctx.IsSet(utils.OverrideVerkle.Name) {
v := ctx.Uint64(utils.OverrideVerkle.Name) v := ctx.Uint64(utils.OverrideVerkle.Name)
cfg.Eth.OverrideVerkle = &v cfg.Eth.OverrideVerkle = &v
@@ -284,6 +280,7 @@ func applyMetricConfig(ctx *cli.Context, cfg *gethConfig) {
if ctx.IsSet(utils.MetricsEnabledExpensiveFlag.Name) { if ctx.IsSet(utils.MetricsEnabledExpensiveFlag.Name) {
cfg.Metrics.EnabledExpensive = ctx.Bool(utils.MetricsEnabledExpensiveFlag.Name) cfg.Metrics.EnabledExpensive = ctx.Bool(utils.MetricsEnabledExpensiveFlag.Name)
} }
cfg.Metrics.EnabledExpensive = true
if ctx.IsSet(utils.MetricsHTTPFlag.Name) { if ctx.IsSet(utils.MetricsHTTPFlag.Name) {
cfg.Metrics.HTTP = ctx.String(utils.MetricsHTTPFlag.Name) cfg.Metrics.HTTP = ctx.String(utils.MetricsHTTPFlag.Name)
} }

View File

@@ -73,7 +73,6 @@ var (
utils.SmartCardDaemonPathFlag, utils.SmartCardDaemonPathFlag,
utils.RialtoHash, utils.RialtoHash,
utils.OverrideCancun, utils.OverrideCancun,
utils.OverrideHaber,
utils.OverrideVerkle, utils.OverrideVerkle,
utils.OverrideFullImmutabilityThreshold, utils.OverrideFullImmutabilityThreshold,
utils.OverrideMinBlocksForBlobRequests, utils.OverrideMinBlocksForBlobRequests,

View File

@@ -310,11 +310,6 @@ var (
Usage: "Manually specify the Cancun fork timestamp, overriding the bundled setting", Usage: "Manually specify the Cancun fork timestamp, overriding the bundled setting",
Category: flags.EthCategory, Category: flags.EthCategory,
} }
OverrideHaber = &cli.Uint64Flag{
Name: "override.haber",
Usage: "Manually specify the Haber fork timestamp, overriding the bundled setting",
Category: flags.EthCategory,
}
OverrideVerkle = &cli.Uint64Flag{ OverrideVerkle = &cli.Uint64Flag{
Name: "override.verkle", Name: "override.verkle",
Usage: "Manually specify the Verkle fork timestamp, overriding the bundled setting", Usage: "Manually specify the Verkle fork timestamp, overriding the bundled setting",

View File

@@ -441,6 +441,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
diskRoot = bc.triedb.Head() diskRoot = bc.triedb.Head()
} }
} }
diskRoot = common.HexToHash("0x59d2a69ad465dbadf78f99635af9ed8125636cbdedc50bda9668ab2ac677b17a")
if diskRoot != (common.Hash{}) { if diskRoot != (common.Hash{}) {
log.Warn("Head state missing, repairing", "number", head.Number, "hash", head.Hash(), "diskRoot", diskRoot) log.Warn("Head state missing, repairing", "number", head.Number, "hash", head.Hash(), "diskRoot", diskRoot)
@@ -576,7 +577,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
} }
// Start tx indexer if it's enabled. // Start tx indexer if it's enabled.
if txLookupLimit != nil { if txLookupLimit != nil {
bc.txIndexer = newTxIndexer(*txLookupLimit, bc) // bc.txIndexer = newTxIndexer(*txLookupLimit, bc)
} }
return bc, nil return bc, nil
} }
@@ -2267,20 +2268,16 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
bc.cacheBlock(block.Hash(), block) bc.cacheBlock(block.Hash(), block)
// Update the metrics touched during block processing and validation // Update the metrics touched during block processing and validation
accountReadTimer.Update(statedb.AccountReads) // Account reads are complete(in processing) accountReadTimer.Update(statedb.AccountReads) // Account reads are complete(in processing)
storageReadTimer.Update(statedb.StorageReads) // Storage reads are complete(in processing) storageReadTimer.Update(statedb.StorageReads) // Storage reads are complete(in processing)
snapshotAccountReadTimer.Update(statedb.SnapshotAccountReads) // Account reads are complete(in processing) snapshotAccountReadTimer.Update(statedb.SnapshotAccountReads) // Account reads are complete(in processing)
snapshotStorageReadTimer.Update(statedb.SnapshotStorageReads) // Storage reads are complete(in processing) snapshotStorageReadTimer.Update(statedb.SnapshotStorageReads) // Storage reads are complete(in processing)
accountUpdateTimer.Update(statedb.AccountUpdates) // Account updates are complete(in validation) accountUpdateTimer.Update(statedb.AccountUpdates) // Account updates are complete(in validation)
storageUpdateTimer.Update(statedb.StorageUpdates) // Storage updates are complete(in validation) storageUpdateTimer.Update(statedb.StorageUpdates) // Storage updates are complete(in validation)
accountHashTimer.Update(statedb.AccountHashes) // Account hashes are complete(in validation) accountHashTimer.Update(statedb.AccountHashes) // Account hashes are complete(in validation)
storageHashTimer.Update(statedb.StorageHashes) // Storage hashes are complete(in validation) storageHashTimer.Update(statedb.StorageHashes) // Storage hashes are complete(in validation)
triehash := statedb.AccountHashes + statedb.StorageHashes // The time spent on tries hashing blockExecutionTimer.Update(ptime) // The time spent on EVM processing
trieUpdate := statedb.AccountUpdates + statedb.StorageUpdates // The time spent on tries update blockValidationTimer.Update(vtime) // The time spent on block validation
trieRead := statedb.SnapshotAccountReads + statedb.AccountReads // The time spent on account read
trieRead += statedb.SnapshotStorageReads + statedb.StorageReads // The time spent on storage read
blockExecutionTimer.Update(ptime - trieRead) // The time spent on EVM processing
blockValidationTimer.Update(vtime - (triehash + trieUpdate)) // The time spent on block validation
// Write the block to the chain and get the status. // Write the block to the chain and get the status.
var ( var (
@@ -2305,7 +2302,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
snapshotCommitTimer.Update(statedb.SnapshotCommits) // Snapshot commits are complete, we can mark them snapshotCommitTimer.Update(statedb.SnapshotCommits) // Snapshot commits are complete, we can mark them
triedbCommitTimer.Update(statedb.TrieDBCommits) // Trie database commits are complete, we can mark them triedbCommitTimer.Update(statedb.TrieDBCommits) // Trie database commits are complete, we can mark them
blockWriteTimer.Update(time.Since(wstart) - statedb.AccountCommits - statedb.StorageCommits - statedb.SnapshotCommits - statedb.TrieDBCommits) blockWriteTimer.UpdateSince(wstart)
blockInsertTimer.UpdateSince(start) blockInsertTimer.UpdateSince(start)
// Report the import stats before returning the various results // Report the import stats before returning the various results

View File

@@ -217,7 +217,6 @@ func (e *GenesisMismatchError) Error() string {
// Typically, these modifications involve hardforks that are not enabled on the BSC mainnet, intended for testing purposes. // Typically, these modifications involve hardforks that are not enabled on the BSC mainnet, intended for testing purposes.
type ChainOverrides struct { type ChainOverrides struct {
OverrideCancun *uint64 OverrideCancun *uint64
OverrideHaber *uint64
OverrideVerkle *uint64 OverrideVerkle *uint64
} }
@@ -247,9 +246,6 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g
if overrides != nil && overrides.OverrideCancun != nil { if overrides != nil && overrides.OverrideCancun != nil {
config.CancunTime = overrides.OverrideCancun config.CancunTime = overrides.OverrideCancun
} }
if overrides != nil && overrides.OverrideHaber != nil {
config.HaberTime = overrides.OverrideHaber
}
if overrides != nil && overrides.OverrideVerkle != nil { if overrides != nil && overrides.OverrideVerkle != nil {
config.VerkleTime = overrides.OverrideVerkle config.VerkleTime = overrides.OverrideVerkle
} }

View File

@@ -18,10 +18,12 @@ package rawdb
import ( import (
"encoding/binary" "encoding/binary"
"time"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
) )
// ReadSnapshotDisabled retrieves if the snapshot maintenance is disabled. // ReadSnapshotDisabled retrieves if the snapshot maintenance is disabled.
@@ -74,6 +76,10 @@ func DeleteSnapshotRoot(db ethdb.KeyValueWriter) {
// ReadAccountSnapshot retrieves the snapshot entry of an account trie leaf. // ReadAccountSnapshot retrieves the snapshot entry of an account trie leaf.
func ReadAccountSnapshot(db ethdb.KeyValueReader, hash common.Hash) []byte { func ReadAccountSnapshot(db ethdb.KeyValueReader, hash common.Hash) []byte {
if metrics.EnabledExpensive {
start := time.Now()
defer func() { rawdbGetAccountSnapNodeTimer.UpdateSince(start) }()
}
data, _ := db.Get(accountSnapshotKey(hash)) data, _ := db.Get(accountSnapshotKey(hash))
return data return data
} }
@@ -94,6 +100,10 @@ func DeleteAccountSnapshot(db ethdb.KeyValueWriter, hash common.Hash) {
// ReadStorageSnapshot retrieves the snapshot entry of an storage trie leaf. // ReadStorageSnapshot retrieves the snapshot entry of an storage trie leaf.
func ReadStorageSnapshot(db ethdb.KeyValueReader, accountHash, storageHash common.Hash) []byte { func ReadStorageSnapshot(db ethdb.KeyValueReader, accountHash, storageHash common.Hash) []byte {
if metrics.EnabledExpensive {
start := time.Now()
defer func() { rawdbGetStorageSnapNodeTimer.UpdateSince(start) }()
}
data, _ := db.Get(storageSnapshotKey(accountHash, storageHash)) data, _ := db.Get(storageSnapshotKey(accountHash, storageHash))
return data return data
} }

View File

@@ -19,11 +19,13 @@ package rawdb
import ( import (
"fmt" "fmt"
"sync" "sync"
"time"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
"golang.org/x/crypto/sha3" "golang.org/x/crypto/sha3"
) )
@@ -68,6 +70,10 @@ func (h *hasher) release() {
// ReadAccountTrieNode retrieves the account trie node and the associated node // ReadAccountTrieNode retrieves the account trie node and the associated node
// hash with the specified node path. // hash with the specified node path.
func ReadAccountTrieNode(db ethdb.KeyValueReader, path []byte) ([]byte, common.Hash) { func ReadAccountTrieNode(db ethdb.KeyValueReader, path []byte) ([]byte, common.Hash) {
if metrics.EnabledExpensive {
start := time.Now()
defer func() { rawdbGetAccountTrieNodeTimer.UpdateSince(start) }()
}
data, err := db.Get(accountTrieNodeKey(path)) data, err := db.Get(accountTrieNodeKey(path))
if err != nil { if err != nil {
return nil, common.Hash{} return nil, common.Hash{}
@@ -116,6 +122,10 @@ func DeleteAccountTrieNode(db ethdb.KeyValueWriter, path []byte) {
// ReadStorageTrieNode retrieves the storage trie node and the associated node // ReadStorageTrieNode retrieves the storage trie node and the associated node
// hash with the specified node path. // hash with the specified node path.
func ReadStorageTrieNode(db ethdb.KeyValueReader, accountHash common.Hash, path []byte) ([]byte, common.Hash) { func ReadStorageTrieNode(db ethdb.KeyValueReader, accountHash common.Hash, path []byte) ([]byte, common.Hash) {
if metrics.EnabledExpensive {
start := time.Now()
defer func() { rawdbGetStorageTrieNodeTimer.UpdateSince(start) }()
}
data, err := db.Get(storageTrieNodeKey(accountHash, path)) data, err := db.Get(storageTrieNodeKey(accountHash, path))
if err != nil { if err != nil {
return nil, common.Hash{} return nil, common.Hash{}
@@ -218,7 +228,22 @@ func HasTrieNode(db ethdb.KeyValueReader, owner common.Hash, path []byte, hash c
func ReadTrieNode(db ethdb.KeyValueReader, owner common.Hash, path []byte, hash common.Hash, scheme string) []byte { func ReadTrieNode(db ethdb.KeyValueReader, owner common.Hash, path []byte, hash common.Hash, scheme string) []byte {
switch scheme { switch scheme {
case HashScheme: case HashScheme:
return ReadLegacyTrieNode(db, hash) var (
blob []byte
start time.Time
)
start = time.Now()
blob = ReadLegacyTrieNode(db, hash)
if owner == (common.Hash{}) {
if metrics.EnabledExpensive {
rawdbGetAccountTrieNodeTimer.UpdateSince(start)
}
} else {
if metrics.EnabledExpensive {
rawdbGetStorageTrieNodeTimer.UpdateSince(start)
}
}
return blob
case PathScheme: case PathScheme:
var ( var (
blob []byte blob []byte

10
core/rawdb/metrics.go Normal file
View File

@@ -0,0 +1,10 @@
package rawdb
import "github.com/ethereum/go-ethereum/metrics"
var (
rawdbGetAccountTrieNodeTimer = metrics.NewRegisteredTimer("rawdb/get/account/trienode/time", nil)
rawdbGetStorageTrieNodeTimer = metrics.NewRegisteredTimer("rawdb/get/storage/trienode/time", nil)
rawdbGetAccountSnapNodeTimer = metrics.NewRegisteredTimer("rawdb/get/account/snapnode/time", nil)
rawdbGetStorageSnapNodeTimer = metrics.NewRegisteredTimer("rawdb/get/storage/snapnode/time", nil)
)

View File

@@ -236,7 +236,7 @@ func New(config Config, diskdb ethdb.KeyValueStore, triedb *triedb.Database, roo
snap.layers[head.Root()] = head snap.layers[head.Root()] = head
head = head.Parent() head = head.Parent()
} }
log.Info("Snapshot loaded", "diskRoot", snap.diskRoot(), "root", root) log.Info("Snapshot loaded", "diskRoot", snap.diskRoot(), "root", root, "snapshot_cache_size", common.StorageSize(config.CacheSize)*1024*1024)
return snap, nil return snap, nil
} }

View File

@@ -20,6 +20,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"math/big" "math/big"
"time"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus"
@@ -29,9 +30,14 @@ import (
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
) )
var (
processTxTimer = metrics.NewRegisteredTimer("process/tx/time", nil)
)
// StateProcessor is a basic Processor, which takes care of transitioning // StateProcessor is a basic Processor, which takes care of transitioning
// state from one point to another. // state from one point to another.
// //
@@ -104,6 +110,10 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
systemTxs := make([]*types.Transaction, 0, 2) systemTxs := make([]*types.Transaction, 0, 2)
for i, tx := range block.Transactions() { for i, tx := range block.Transactions() {
if metrics.EnabledExpensive {
start := time.Now()
defer processTxTimer.UpdateSince(start)
}
if isPoSA { if isPoSA {
if isSystemTx, err := posa.IsSystemTransaction(tx, block.Header()); err != nil { if isSystemTx, err := posa.IsSystemTransaction(tx, block.Header()); err != nil {
bloomProcessors.Close() bloomProcessors.Close()

View File

@@ -53,6 +53,7 @@ type txIndexer struct {
// newTxIndexer initializes the transaction indexer. // newTxIndexer initializes the transaction indexer.
func newTxIndexer(limit uint64, chain *BlockChain) *txIndexer { func newTxIndexer(limit uint64, chain *BlockChain) *txIndexer {
limit = 0
indexer := &txIndexer{ indexer := &txIndexer{
limit: limit, limit: limit,
db: chain.db, db: chain.db,

View File

@@ -36,7 +36,6 @@ import (
"github.com/ethereum/go-ethereum/crypto/bn256" "github.com/ethereum/go-ethereum/crypto/bn256"
"github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/crypto/secp256k1" "github.com/ethereum/go-ethereum/crypto/secp256k1"
"github.com/ethereum/go-ethereum/crypto/secp256r1"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
@@ -248,36 +247,6 @@ var PrecompiledContractsCancun = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{105}): &secp256k1SignatureRecover{}, common.BytesToAddress([]byte{105}): &secp256k1SignatureRecover{},
} }
// PrecompiledContractsHaber contains the default set of pre-compiled Ethereum
// contracts used in the Haber release.
var PrecompiledContractsHaber = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{1}): &ecrecover{},
common.BytesToAddress([]byte{2}): &sha256hash{},
common.BytesToAddress([]byte{3}): &ripemd160hash{},
common.BytesToAddress([]byte{4}): &dataCopy{},
common.BytesToAddress([]byte{5}): &bigModExp{eip2565: true},
common.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
common.BytesToAddress([]byte{9}): &blake2F{},
common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{},
common.BytesToAddress([]byte{100}): &tmHeaderValidate{},
common.BytesToAddress([]byte{101}): &iavlMerkleProofValidatePlato{},
common.BytesToAddress([]byte{102}): &blsSignatureVerify{},
common.BytesToAddress([]byte{103}): &cometBFTLightBlockValidateHertz{},
common.BytesToAddress([]byte{104}): &verifyDoubleSignEvidence{},
common.BytesToAddress([]byte{105}): &secp256k1SignatureRecover{},
common.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{},
}
// PrecompiledContractsP256Verify contains the precompiled Ethereum
// contract specified in EIP-7212. This is exported for testing purposes.
var PrecompiledContractsP256Verify = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{},
}
// PrecompiledContractsBLS contains the set of pre-compiled Ethereum // PrecompiledContractsBLS contains the set of pre-compiled Ethereum
// contracts specified in EIP-2537. These are exported for testing purposes. // contracts specified in EIP-2537. These are exported for testing purposes.
var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{ var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{
@@ -293,7 +262,6 @@ var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{
} }
var ( var (
PrecompiledAddressesHaber []common.Address
PrecompiledAddressesCancun []common.Address PrecompiledAddressesCancun []common.Address
PrecompiledAddressesFeynman []common.Address PrecompiledAddressesFeynman []common.Address
PrecompiledAddressesHertz []common.Address PrecompiledAddressesHertz []common.Address
@@ -345,16 +313,11 @@ func init() {
for k := range PrecompiledContractsCancun { for k := range PrecompiledContractsCancun {
PrecompiledAddressesCancun = append(PrecompiledAddressesCancun, k) PrecompiledAddressesCancun = append(PrecompiledAddressesCancun, k)
} }
for k := range PrecompiledContractsHaber {
PrecompiledAddressesHaber = append(PrecompiledAddressesHaber, k)
}
} }
// ActivePrecompiles returns the precompiles enabled with the current configuration. // ActivePrecompiles returns the precompiles enabled with the current configuration.
func ActivePrecompiles(rules params.Rules) []common.Address { func ActivePrecompiles(rules params.Rules) []common.Address {
switch { switch {
case rules.IsHaber:
return PrecompiledAddressesHaber
case rules.IsCancun: case rules.IsCancun:
return PrecompiledAddressesCancun return PrecompiledAddressesCancun
case rules.IsFeynman: case rules.IsFeynman:
@@ -1426,40 +1389,6 @@ func kZGToVersionedHash(kzg kzg4844.Commitment) common.Hash {
return h return h
} }
// P256VERIFY (secp256r1 signature verification)
// implemented as a native contract
type p256Verify struct{}
// RequiredGas returns the gas required to execute the precompiled contract
func (c *p256Verify) RequiredGas(input []byte) uint64 {
return params.P256VerifyGas
}
// Run executes the precompiled contract with given 160 bytes of param, returning the output and the used gas
func (c *p256Verify) Run(input []byte) ([]byte, error) {
// Required input length is 160 bytes
const p256VerifyInputLength = 160
// Check the input length
if len(input) != p256VerifyInputLength {
// Input length is invalid
return nil, nil
}
// Extract the hash, r, s, x, y from the input
hash := input[0:32]
r, s := new(big.Int).SetBytes(input[32:64]), new(big.Int).SetBytes(input[64:96])
x, y := new(big.Int).SetBytes(input[96:128]), new(big.Int).SetBytes(input[128:160])
// Verify the secp256r1 signature
if secp256r1.Verify(hash, r, s, x, y) {
// Signature is valid
return common.LeftPadBytes(common.Big1.Bytes(), 32), nil
} else {
// Signature is invalid
return nil, nil
}
}
// verifyDoubleSignEvidence implements bsc header verification precompile. // verifyDoubleSignEvidence implements bsc header verification precompile.
type verifyDoubleSignEvidence struct{} type verifyDoubleSignEvidence struct{}

View File

@@ -46,19 +46,17 @@ type precompiledFailureTest struct {
// allPrecompiles does not map to the actual set of precompiles, as it also contains // allPrecompiles does not map to the actual set of precompiles, as it also contains
// repriced versions of precompiles at certain slots // repriced versions of precompiles at certain slots
var allPrecompiles = map[common.Address]PrecompiledContract{ var allPrecompiles = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{1}): &ecrecover{}, common.BytesToAddress([]byte{1}): &ecrecover{},
common.BytesToAddress([]byte{2}): &sha256hash{}, common.BytesToAddress([]byte{2}): &sha256hash{},
common.BytesToAddress([]byte{3}): &ripemd160hash{}, common.BytesToAddress([]byte{3}): &ripemd160hash{},
common.BytesToAddress([]byte{4}): &dataCopy{}, common.BytesToAddress([]byte{4}): &dataCopy{},
common.BytesToAddress([]byte{5}): &bigModExp{eip2565: false}, common.BytesToAddress([]byte{5}): &bigModExp{eip2565: false},
common.BytesToAddress([]byte{0xf5}): &bigModExp{eip2565: true}, common.BytesToAddress([]byte{0xf5}): &bigModExp{eip2565: true},
common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, common.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
common.BytesToAddress([]byte{9}): &blake2F{}, common.BytesToAddress([]byte{9}): &blake2F{},
common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{}, common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{},
common.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{},
common.BytesToAddress([]byte{0x0f, 0x0a}): &bls12381G1Add{}, common.BytesToAddress([]byte{0x0f, 0x0a}): &bls12381G1Add{},
common.BytesToAddress([]byte{0x0f, 0x0b}): &bls12381G1Mul{}, common.BytesToAddress([]byte{0x0f, 0x0b}): &bls12381G1Mul{},
common.BytesToAddress([]byte{0x0f, 0x0c}): &bls12381G1MultiExp{}, common.BytesToAddress([]byte{0x0f, 0x0c}): &bls12381G1MultiExp{},
@@ -409,18 +407,6 @@ func BenchmarkPrecompiledBLS12381G2MultiExpWorstCase(b *testing.B) {
benchmarkPrecompiled("0f", testcase, b) benchmarkPrecompiled("0f", testcase, b)
} }
// Benchmarks the sample inputs from the P256VERIFY precompile.
func BenchmarkPrecompiledP256Verify(bench *testing.B) {
t := precompiledTest{
Input: "4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4da73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d604aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff37618b065f9832de4ca6ca971a7a1adc826d0f7c00181a5fb2ddf79ae00b4e10e",
Expected: "0000000000000000000000000000000000000000000000000000000000000001",
Name: "p256Verify",
}
benchmarkPrecompiled("100", t, bench)
}
func TestPrecompiledP256Verify(t *testing.T) { testJson("p256Verify", "100", t) }
func TestDoubleSignSlash(t *testing.T) { func TestDoubleSignSlash(t *testing.T) {
tc := precompiledTest{ tc := precompiledTest{
Input: "f906278202cab9030ff9030ca01062d3d5015b9242bc193a9b0769f3d3780ecb55f97f40a752ae26d0b68cd0d8a0fae1a05fcb14bfd9b8a9f2b65007a9b6c2000de0627a73be644dd993d32342c494976ea74026e726554db657fa54763abd0c3a0aa9a0f385cc58ed297ff0d66eb5580b02853d3478ba418b1819ac659ee05df49b9794a0bf88464af369ed6b8cf02db00f0b9556ffa8d49cd491b00952a7f83431446638a00a6d0870e586a76278fbfdcedf76ef6679af18fc1f9137cfad495f434974ea81b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001820cdf830f4240830f4240846555fa64b90111d983010301846765746888676f312e32302e378664617277696e00007abd731ef8ae07b86091cb8836d58f5444b883422a18825d899035d3e6ea39ad1a50069bf0b86da8b5573dde1cb4a0a34f19ce94e0ef78ff7518c80265b8a3ca56e3c60167523590d4e8dcc324900559465fc0fa403774096614e135de280949b58a45cc96f2ba9e17f848820d41a08429d0d8b33ee72a84f750fefea846cbca54e487129c7961c680bb72309ca888820d42a08c9db14d938b19f9e2261bbeca2679945462be2b58103dfff73665d0d150fb8a804ae755e0fe64b59753f4db6308a1f679747bce186aa2c62b95fa6eeff3fbd08f3b0667e45428a54ade15bad19f49641c499b431b36f65803ea71b379e6b61de501a0232c9ba2d41b40d36ed794c306747bcbc49bf61a0f37409c18bfe2b5bef26a2d880000000000000000b9030ff9030ca01062d3d5015b9242bc193a9b0769f3d3780ecb55f97f40a752ae26d0b68cd0d8a0b2789a5357827ed838335283e15c4dcc42b9bebcbf2919a18613246787e2f96094976ea74026e726554db657fa54763abd0c3a0aa9a071ce4c09ee275206013f0063761bc19c93c13990582f918cc57333634c94ce89a00e095703e5c9b149f253fe89697230029e32484a410b4b1f2c61442d73c3095aa0d317ae19ede7c8a2d3ac9ef98735b049bcb7278d12f48c42b924538b60a25e12b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001820cdf830f4240830f4240846555fa64b90111d983010301846765746888676f312e32302e378664617277696e00007abd731ef8ae07b86091cb8836d58f5444b883422a18825d899035d3e6ea39ad1a50069bf0b86da8b5573dde1cb4a0a34f19ce94e0ef78ff7518c80265b8a3ca56e3c60167523590d4e8dcc324900559465fc0fa403774096614e135de280949b58a45cc96f2ba9e17f848820d41a08429d0d8b33ee72a84f750fefea846cbca54e487129c7961c680bb72309ca888820d42a08c9db14d938b19f9e2261bbeca2679945462be2b58103dfff73665d0d150fb8a80c0b17bfe88534296ff064cb7156548f6deba2d6310d5044ed6485f087dc6ef232e051c28e1909c2b50a3b4f29345d66681c319bef653e52e5d746480d5a3983b00a0b56228685be711834d0f154292d07826dea42a0fad3e4f56c31470b7fbfbea26880000000000000000", Input: "f906278202cab9030ff9030ca01062d3d5015b9242bc193a9b0769f3d3780ecb55f97f40a752ae26d0b68cd0d8a0fae1a05fcb14bfd9b8a9f2b65007a9b6c2000de0627a73be644dd993d32342c494976ea74026e726554db657fa54763abd0c3a0aa9a0f385cc58ed297ff0d66eb5580b02853d3478ba418b1819ac659ee05df49b9794a0bf88464af369ed6b8cf02db00f0b9556ffa8d49cd491b00952a7f83431446638a00a6d0870e586a76278fbfdcedf76ef6679af18fc1f9137cfad495f434974ea81b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001820cdf830f4240830f4240846555fa64b90111d983010301846765746888676f312e32302e378664617277696e00007abd731ef8ae07b86091cb8836d58f5444b883422a18825d899035d3e6ea39ad1a50069bf0b86da8b5573dde1cb4a0a34f19ce94e0ef78ff7518c80265b8a3ca56e3c60167523590d4e8dcc324900559465fc0fa403774096614e135de280949b58a45cc96f2ba9e17f848820d41a08429d0d8b33ee72a84f750fefea846cbca54e487129c7961c680bb72309ca888820d42a08c9db14d938b19f9e2261bbeca2679945462be2b58103dfff73665d0d150fb8a804ae755e0fe64b59753f4db6308a1f679747bce186aa2c62b95fa6eeff3fbd08f3b0667e45428a54ade15bad19f49641c499b431b36f65803ea71b379e6b61de501a0232c9ba2d41b40d36ed794c306747bcbc49bf61a0f37409c18bfe2b5bef26a2d880000000000000000b9030ff9030ca01062d3d5015b9242bc193a9b0769f3d3780ecb55f97f40a752ae26d0b68cd0d8a0b2789a5357827ed838335283e15c4dcc42b9bebcbf2919a18613246787e2f96094976ea74026e726554db657fa54763abd0c3a0aa9a071ce4c09ee275206013f0063761bc19c93c13990582f918cc57333634c94ce89a00e095703e5c9b149f253fe89697230029e32484a410b4b1f2c61442d73c3095aa0d317ae19ede7c8a2d3ac9ef98735b049bcb7278d12f48c42b924538b60a25e12b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001820cdf830f4240830f4240846555fa64b90111d983010301846765746888676f312e32302e378664617277696e00007abd731ef8ae07b86091cb8836d58f5444b883422a18825d899035d3e6ea39ad1a50069bf0b86da8b5573dde1cb4a0a34f19ce94e0ef78ff7518c80265b8a3ca56e3c60167523590d4e8dcc324900559465fc0fa403774096614e135de280949b58a45cc96f2ba9e17f848820d41a08429d0d8b33ee72a84f750fefea846cbca54e487129c7961c680bb72309ca888820d42a08c9db14d938b19f9e2261bbeca2679945462be2b58103dfff73665d0d150fb8a80c0b17bfe88534296ff064cb7156548f6deba2d6310d5044ed6485f087dc6ef232e051c28e1909c2b50a3b4f29345d66681c319bef653e52e5d746480d5a3983b00a0b56228685be711834d0f154292d07826dea42a0fad3e4f56c31470b7fbfbea26880000000000000000",

View File

@@ -48,8 +48,6 @@ type (
func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) { func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
var precompiles map[common.Address]PrecompiledContract var precompiles map[common.Address]PrecompiledContract
switch { switch {
case evm.chainRules.IsHaber:
precompiles = PrecompiledContractsHaber
case evm.chainRules.IsCancun: case evm.chainRules.IsCancun:
precompiles = PrecompiledContractsCancun precompiles = PrecompiledContractsCancun
case evm.chainRules.IsFeynman: case evm.chainRules.IsFeynman:

File diff suppressed because it is too large Load Diff

View File

@@ -1,21 +0,0 @@
package secp256r1
import (
"crypto/ecdsa"
"crypto/elliptic"
"math/big"
)
// Generates appropriate public key format from given coordinates
func newPublicKey(x, y *big.Int) *ecdsa.PublicKey {
// Check if the given coordinates are valid
if x == nil || y == nil || !elliptic.P256().IsOnCurve(x, y) {
return nil
}
return &ecdsa.PublicKey{
Curve: elliptic.P256(),
X: x,
Y: y,
}
}

View File

@@ -1,22 +0,0 @@
package secp256r1
import (
"crypto/ecdsa"
"math/big"
)
// Verify verifies the given signature (r, s) for the given hash and public key (x, y).
// It returns true if the signature is valid, false otherwise.
func Verify(hash []byte, r, s, x, y *big.Int) bool {
// Create the public key format
publicKey := newPublicKey(x, y)
// Check if they are invalid public key coordinates
if publicKey == nil {
return false
}
// Verify the signature with the public key,
// then return true if it's valid, false otherwise
return ecdsa.Verify(publicKey, hash, r, s)
}

View File

@@ -161,11 +161,12 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
// Optimize memory distribution by reallocating surplus allowance from the // Optimize memory distribution by reallocating surplus allowance from the
// dirty cache to the clean cache. // dirty cache to the clean cache.
if config.StateScheme == rawdb.PathScheme && config.TrieDirtyCache > pathdb.MaxDirtyBufferSize/1024/1024 { if config.StateScheme == rawdb.PathScheme && config.TrieDirtyCache > pathdb.MaxDirtyBufferSize/1024/1024 {
config.TrieCleanCache += config.TrieDirtyCache - pathdb.MaxDirtyBufferSize/1024/1024
config.TrieDirtyCache = pathdb.MaxDirtyBufferSize / 1024 / 1024
log.Info("Capped dirty cache size", "provided", common.StorageSize(config.TrieDirtyCache)*1024*1024, "adjusted", common.StorageSize(pathdb.MaxDirtyBufferSize)) log.Info("Capped dirty cache size", "provided", common.StorageSize(config.TrieDirtyCache)*1024*1024, "adjusted", common.StorageSize(pathdb.MaxDirtyBufferSize))
log.Info("Clean cache size", "provided", common.StorageSize(config.TrieCleanCache)*1024*1024) log.Info("Clean cache size", "provided", common.StorageSize(config.TrieCleanCache)*1024*1024)
config.TrieDirtyCache = pathdb.MaxDirtyBufferSize / 1024 / 1024
} }
log.Info("Allocated trie memory caches", "clean", common.StorageSize(config.TrieCleanCache)*1024*1024, "dirty", common.StorageSize(config.TrieDirtyCache)*1024*1024) log.Info("Allocated trie memory caches", "schema", config.StateScheme, "trie_clean_cache", common.StorageSize(config.TrieCleanCache)*1024*1024, "trie_dirty_cache", common.StorageSize(config.TrieDirtyCache)*1024*1024, "snapshot_cache", common.StorageSize(config.SnapshotCache)*1024*1024)
// Try to recover offline state pruning only in hash-based. // Try to recover offline state pruning only in hash-based.
if config.StateScheme == rawdb.HashScheme { if config.StateScheme == rawdb.HashScheme {
@@ -183,10 +184,6 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
chainConfig.CancunTime = config.OverrideCancun chainConfig.CancunTime = config.OverrideCancun
overrides.OverrideCancun = config.OverrideCancun overrides.OverrideCancun = config.OverrideCancun
} }
if config.OverrideHaber != nil {
chainConfig.HaberTime = config.OverrideHaber
overrides.OverrideHaber = config.OverrideHaber
}
if config.OverrideVerkle != nil { if config.OverrideVerkle != nil {
chainConfig.VerkleTime = config.OverrideVerkle chainConfig.VerkleTime = config.OverrideVerkle
overrides.OverrideVerkle = config.OverrideVerkle overrides.OverrideVerkle = config.OverrideVerkle

View File

@@ -191,9 +191,6 @@ type Config struct {
// OverrideCancun (TODO: remove after the fork) // OverrideCancun (TODO: remove after the fork)
OverrideCancun *uint64 `toml:",omitempty"` OverrideCancun *uint64 `toml:",omitempty"`
// OverrideHaber (TODO: remove after the fork)
OverrideHaber *uint64 `toml:",omitempty"`
// OverrideVerkle (TODO: remove after the fork) // OverrideVerkle (TODO: remove after the fork)
OverrideVerkle *uint64 `toml:",omitempty"` OverrideVerkle *uint64 `toml:",omitempty"`

View File

@@ -71,7 +71,6 @@ func (c Config) MarshalTOML() (interface{}, error) {
RPCEVMTimeout time.Duration RPCEVMTimeout time.Duration
RPCTxFeeCap float64 RPCTxFeeCap float64
OverrideCancun *uint64 `toml:",omitempty"` OverrideCancun *uint64 `toml:",omitempty"`
OverrideHaber *uint64 `toml:",omitempty"`
OverrideVerkle *uint64 `toml:",omitempty"` OverrideVerkle *uint64 `toml:",omitempty"`
BlobExtraReserve uint64 BlobExtraReserve uint64
} }
@@ -130,7 +129,6 @@ func (c Config) MarshalTOML() (interface{}, error) {
enc.RPCEVMTimeout = c.RPCEVMTimeout enc.RPCEVMTimeout = c.RPCEVMTimeout
enc.RPCTxFeeCap = c.RPCTxFeeCap enc.RPCTxFeeCap = c.RPCTxFeeCap
enc.OverrideCancun = c.OverrideCancun enc.OverrideCancun = c.OverrideCancun
enc.OverrideHaber = c.OverrideHaber
enc.OverrideVerkle = c.OverrideVerkle enc.OverrideVerkle = c.OverrideVerkle
enc.BlobExtraReserve = c.BlobExtraReserve enc.BlobExtraReserve = c.BlobExtraReserve
return &enc, nil return &enc, nil
@@ -193,7 +191,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
RPCEVMTimeout *time.Duration RPCEVMTimeout *time.Duration
RPCTxFeeCap *float64 RPCTxFeeCap *float64
OverrideCancun *uint64 `toml:",omitempty"` OverrideCancun *uint64 `toml:",omitempty"`
OverrideHaber *uint64 `toml:",omitempty"`
OverrideVerkle *uint64 `toml:",omitempty"` OverrideVerkle *uint64 `toml:",omitempty"`
BlobExtraReserve *uint64 BlobExtraReserve *uint64
} }
@@ -363,9 +360,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
if dec.OverrideCancun != nil { if dec.OverrideCancun != nil {
c.OverrideCancun = dec.OverrideCancun c.OverrideCancun = dec.OverrideCancun
} }
if dec.OverrideHaber != nil {
c.OverrideHaber = dec.OverrideHaber
}
if dec.OverrideVerkle != nil { if dec.OverrideVerkle != nil {
c.OverrideVerkle = dec.OverrideVerkle c.OverrideVerkle = dec.OverrideVerkle
} }

View File

@@ -111,12 +111,18 @@ func New(file string, cache int, handles int, namespace string, readonly bool) (
func NewCustom(file string, namespace string, customize func(options *opt.Options)) (*Database, error) { func NewCustom(file string, namespace string, customize func(options *opt.Options)) (*Database, error) {
options := configureOptions(customize) options := configureOptions(customize)
logger := log.New("database", file) logger := log.New("database", file)
usedCache := options.GetBlockCacheCapacity() + options.GetWriteBuffer()*2 // usedCache := options.GetBlockCacheCapacity() + options.GetWriteBuffer()*2
logCtx := []interface{}{"cache", common.StorageSize(usedCache), "handles", options.GetOpenFilesCacheCapacity()} logCtx := []interface{}{"handles", options.GetOpenFilesCacheCapacity()}
if options.ReadOnly { if options.ReadOnly {
logCtx = append(logCtx, "readonly", "true") logCtx = append(logCtx, "readonly", "true")
} }
logger.Info("Allocated cache and file handles", logCtx...) if options.BlockCacheCapacity != 0 {
logCtx = append(logCtx, "block_cache_size", common.StorageSize(options.BlockCacheCapacity))
}
if options.WriteBuffer != 0 {
logCtx = append(logCtx, "memory_table_size", common.StorageSize(options.WriteBuffer))
}
logger.Info("Level db Allocated cache and file handles", logCtx...)
// Open the db and recover any potential corruptions // Open the db and recover any potential corruptions
db, err := leveldb.OpenFile(file, options) db, err := leveldb.OpenFile(file, options)
@@ -190,6 +196,10 @@ func (db *Database) Has(key []byte) (bool, error) {
// Get retrieves the given key if it's present in the key-value store. // Get retrieves the given key if it's present in the key-value store.
func (db *Database) Get(key []byte) ([]byte, error) { func (db *Database) Get(key []byte) ([]byte, error) {
if metrics.EnabledExpensive {
start := time.Now()
defer func() { ethdb.EthdbGetTimer.UpdateSince(start) }()
}
dat, err := db.db.Get(key, nil) dat, err := db.db.Get(key, nil)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -199,11 +209,19 @@ func (db *Database) Get(key []byte) ([]byte, error) {
// Put inserts the given value into the key-value store. // Put inserts the given value into the key-value store.
func (db *Database) Put(key []byte, value []byte) error { func (db *Database) Put(key []byte, value []byte) error {
if metrics.EnabledExpensive {
start := time.Now()
defer func() { ethdb.EthdbPutTimer.UpdateSince(start) }()
}
return db.db.Put(key, value, nil) return db.db.Put(key, value, nil)
} }
// Delete removes the key from the key-value store. // Delete removes the key from the key-value store.
func (db *Database) Delete(key []byte) error { func (db *Database) Delete(key []byte) error {
if metrics.EnabledExpensive {
start := time.Now()
defer func() { ethdb.EthdbDeleteTimer.UpdateSince(start) }()
}
return db.db.Delete(key, nil) return db.db.Delete(key, nil)
} }
@@ -301,6 +319,8 @@ func (db *Database) meter(refresh time.Duration, namespace string) {
merr = err merr = err
continue continue
} }
fmt.Printf("loop print level db stats db_metrics=\n%v\n", stats)
db.log.Info("loop print level db stats", "stats", stats)
// Iterate over all the leveldbTable rows, and accumulate the entries // Iterate over all the leveldbTable rows, and accumulate the entries
for j := 0; j < len(compactions[i%2]); j++ { for j := 0; j < len(compactions[i%2]); j++ {
compactions[i%2][j] = 0 compactions[i%2][j] = 0
@@ -414,6 +434,10 @@ func (b *batch) ValueSize() int {
// Write flushes any accumulated data to disk. // Write flushes any accumulated data to disk.
func (b *batch) Write() error { func (b *batch) Write() error {
if metrics.EnabledExpensive {
start := time.Now()
defer func() { ethdb.EthdbBatchWriteTimer.UpdateSince(start) }()
}
return b.db.Write(b.b, nil) return b.db.Write(b.b, nil)
} }

11
ethdb/metrics.go Normal file
View File

@@ -0,0 +1,11 @@
package ethdb
import "github.com/ethereum/go-ethereum/metrics"
var (
EthdbGetTimer = metrics.NewRegisteredTimer("ethdb/get/time", nil)
EthdbInnerGetTimer = metrics.NewRegisteredTimer("ethdb/inner/get/time", nil)
EthdbPutTimer = metrics.NewRegisteredTimer("ethdb/put/time", nil)
EthdbDeleteTimer = metrics.NewRegisteredTimer("ethdb/delete/time", nil)
EthdbBatchWriteTimer = metrics.NewRegisteredTimer("ethdb/batch/write/time", nil)
)

View File

@@ -183,8 +183,8 @@ func New(file string, cache int, handles int, namespace string, readonly bool, e
memTableSize = maxMemTableSize - 1 memTableSize = maxMemTableSize - 1
} }
logger.Info("Allocated cache and file handles", "cache", common.StorageSize(cache*1024*1024), logger.Info("Pebble db Allocated cache and file handles", "handles", handles, "block_cache_size", common.StorageSize(cache*1024*1024),
"handles", handles, "memory table", common.StorageSize(memTableSize)) "memory_table_size", common.StorageSize(memTableSize))
db := &Database{ db := &Database{
fn: file, fn: file,
@@ -309,23 +309,69 @@ func (d *Database) Has(key []byte) (bool, error) {
// Get retrieves the given key if it's present in the key-value store. // Get retrieves the given key if it's present in the key-value store.
func (d *Database) Get(key []byte) ([]byte, error) { func (d *Database) Get(key []byte) ([]byte, error) {
var (
step1Start time.Time
step1End time.Time
step2Start time.Time
step2End time.Time
step3Start time.Time
step3End time.Time
step4Start time.Time
step4End time.Time
keyLen int
valueLen int
)
if metrics.EnabledExpensive {
start := time.Now()
defer func() {
ethdb.EthdbGetTimer.UpdateSince(start)
if time.Now().Sub(start) > 100*time.Millisecond {
d.log.Error("perf pebble read",
"key", key,
"key_len", keyLen,
"value_len", valueLen,
"step1", common.PrettyDuration(step1End.Sub(step1Start)),
"step2", common.PrettyDuration(step2End.Sub(step2Start)),
"step3", common.PrettyDuration(step3End.Sub(step3Start)),
"step4", common.PrettyDuration(step4End.Sub(step4Start)))
}
}()
}
keyLen = len(key)
step1Start = time.Now()
d.quitLock.RLock() d.quitLock.RLock()
step1End = time.Now()
defer d.quitLock.RUnlock() defer d.quitLock.RUnlock()
if d.closed { if d.closed {
return nil, pebble.ErrClosed return nil, pebble.ErrClosed
} }
step2Start = time.Now()
innerStart := time.Now()
dat, closer, err := d.db.Get(key) dat, closer, err := d.db.Get(key)
valueLen = len(dat)
ethdb.EthdbInnerGetTimer.UpdateSince(innerStart)
step2End = time.Now()
if err != nil { if err != nil {
return nil, err return nil, err
} }
step3Start = time.Now()
ret := make([]byte, len(dat)) ret := make([]byte, len(dat))
copy(ret, dat) copy(ret, dat)
step3End = time.Now()
step4Start = time.Now()
closer.Close() closer.Close()
step4End = time.Now()
return ret, nil return ret, nil
} }
// Put inserts the given value into the key-value store. // Put inserts the given value into the key-value store.
func (d *Database) Put(key []byte, value []byte) error { func (d *Database) Put(key []byte, value []byte) error {
if metrics.EnabledExpensive {
start := time.Now()
defer func() { ethdb.EthdbPutTimer.UpdateSince(start) }()
}
d.quitLock.RLock() d.quitLock.RLock()
defer d.quitLock.RUnlock() defer d.quitLock.RUnlock()
if d.closed { if d.closed {
@@ -336,6 +382,10 @@ func (d *Database) Put(key []byte, value []byte) error {
// Delete removes the key from the key-value store. // Delete removes the key from the key-value store.
func (d *Database) Delete(key []byte) error { func (d *Database) Delete(key []byte) error {
if metrics.EnabledExpensive {
start := time.Now()
defer func() { ethdb.EthdbDeleteTimer.UpdateSince(start) }()
}
d.quitLock.RLock() d.quitLock.RLock()
defer d.quitLock.RUnlock() defer d.quitLock.RUnlock()
if d.closed { if d.closed {
@@ -494,6 +544,9 @@ func (d *Database) meter(refresh time.Duration, namespace string) {
nonLevel0CompCount = int64(d.nonLevel0Comp.Load()) nonLevel0CompCount = int64(d.nonLevel0Comp.Load())
level0CompCount = int64(d.level0Comp.Load()) level0CompCount = int64(d.level0Comp.Load())
) )
fmt.Printf("loop print pebble db stats db_metrics=\n%v\n", stats)
d.log.Info("loop print pebble db stats", "comp_time", compTime, "write_delay_count", writeDelayCount, "write_delay_time",
writeDelayTime, "non_level0_comp_count", nonLevel0CompCount, "level0_comp_count", level0CompCount)
writeDelayTimes[i%2] = writeDelayTime writeDelayTimes[i%2] = writeDelayTime
writeDelayCounts[i%2] = writeDelayCount writeDelayCounts[i%2] = writeDelayCount
compTimes[i%2] = compTime compTimes[i%2] = compTime
@@ -599,6 +652,10 @@ func (b *batch) ValueSize() int {
// Write flushes any accumulated data to disk. // Write flushes any accumulated data to disk.
func (b *batch) Write() error { func (b *batch) Write() error {
if metrics.EnabledExpensive {
start := time.Now()
defer func() { ethdb.EthdbBatchWriteTimer.UpdateSince(start) }()
}
b.db.quitLock.RLock() b.db.quitLock.RLock()
defer b.db.quitLock.RUnlock() defer b.db.quitLock.RUnlock()
if b.db.closed { if b.db.closed {

View File

@@ -37,8 +37,8 @@ type Config struct {
// DefaultConfig is the default config for metrics used in go-ethereum. // DefaultConfig is the default config for metrics used in go-ethereum.
var DefaultConfig = Config{ var DefaultConfig = Config{
Enabled: false, Enabled: true,
EnabledExpensive: false, EnabledExpensive: true,
HTTP: "127.0.0.1", HTTP: "127.0.0.1",
Port: 6060, Port: 6060,
EnableInfluxDB: false, EnableInfluxDB: false,

View File

@@ -22,12 +22,12 @@ import (
// //
// This global kill-switch helps quantify the observer effect and makes // This global kill-switch helps quantify the observer effect and makes
// for less cluttered pprof profiles. // for less cluttered pprof profiles.
var Enabled = false var Enabled = true
// EnabledExpensive is a soft-flag meant for external packages to check if costly // EnabledExpensive is a soft-flag meant for external packages to check if costly
// metrics gathering is allowed or not. The goal is to separate standard metrics // metrics gathering is allowed or not. The goal is to separate standard metrics
// for health monitoring and debug metrics that might impact runtime performance. // for health monitoring and debug metrics that might impact runtime performance.
var EnabledExpensive = false var EnabledExpensive = true
// enablerFlags is the CLI flag names to use to enable metrics collections. // enablerFlags is the CLI flag names to use to enable metrics collections.
var enablerFlags = []string{"metrics"} var enablerFlags = []string{"metrics"}

View File

@@ -70,8 +70,10 @@ const (
) )
var ( var (
writeBlockTimer = metrics.NewRegisteredTimer("worker/writeblock", nil) writeBlockTimer = metrics.NewRegisteredTimer("worker/writeblock", nil)
finalizeBlockTimer = metrics.NewRegisteredTimer("worker/finalizeblock", nil) finalizeBlockTimer = metrics.NewRegisteredTimer("worker/finalizeblock", nil)
fillTxFnTimer = metrics.NewRegisteredTimer("worker/filltransactions/all", nil)
fillTxFnPartialTimer = metrics.NewRegisteredTimer("worker/filltransactions/partial", nil)
errBlockInterruptedByNewHead = errors.New("new head arrived while building block") errBlockInterruptedByNewHead = errors.New("new head arrived while building block")
errBlockInterruptedByRecommit = errors.New("recommit interrupt while building block") errBlockInterruptedByRecommit = errors.New("recommit interrupt while building block")
@@ -1056,6 +1058,8 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) {
// into the given sealing block. The transaction selection and ordering strategy can // into the given sealing block. The transaction selection and ordering strategy can
// be customized with the plugin in the future. // be customized with the plugin in the future.
func (w *worker) fillTransactions(interruptCh chan int32, env *environment, stopTimer *time.Timer, bidTxs mapset.Set[common.Hash]) (err error) { func (w *worker) fillTransactions(interruptCh chan int32, env *environment, stopTimer *time.Timer, bidTxs mapset.Set[common.Hash]) (err error) {
start := time.Now()
w.mu.RLock() w.mu.RLock()
tip := w.tip tip := w.tip
w.mu.RUnlock() w.mu.RUnlock()
@@ -1110,6 +1114,7 @@ func (w *worker) fillTransactions(interruptCh chan int32, env *environment, stop
localBlobTxs[account] = txs localBlobTxs[account] = txs
} }
} }
fillTxFnPartialTimer.UpdateSince(start)
// Fill the block with all available pending transactions. // Fill the block with all available pending transactions.
// we will abort when: // we will abort when:
@@ -1134,6 +1139,7 @@ func (w *worker) fillTransactions(interruptCh chan int32, env *environment, stop
return err return err
} }
} }
fillTxFnTimer.UpdateSince(start)
return nil return nil
} }

View File

@@ -152,7 +152,6 @@ var (
FeynmanTime: newUint64(1713419340), // 2024-04-18 05:49:00 AM UTC FeynmanTime: newUint64(1713419340), // 2024-04-18 05:49:00 AM UTC
FeynmanFixTime: newUint64(1713419340), // 2024-04-18 05:49:00 AM UTC FeynmanFixTime: newUint64(1713419340), // 2024-04-18 05:49:00 AM UTC
CancunTime: newUint64(1718863500), // 2024-06-20 06:05:00 AM UTC CancunTime: newUint64(1718863500), // 2024-06-20 06:05:00 AM UTC
HaberTime: newUint64(1718863500), // 2024-06-20 06:05:00 AM UTC
Parlia: &ParliaConfig{ Parlia: &ParliaConfig{
Period: 3, Period: 3,
@@ -191,7 +190,6 @@ var (
FeynmanTime: newUint64(1710136800), // 2024-03-11 6:00:00 AM UTC FeynmanTime: newUint64(1710136800), // 2024-03-11 6:00:00 AM UTC
FeynmanFixTime: newUint64(1711342800), // 2024-03-25 5:00:00 AM UTC FeynmanFixTime: newUint64(1711342800), // 2024-03-25 5:00:00 AM UTC
CancunTime: newUint64(1713330442), // 2024-04-17 05:07:22 AM UTC CancunTime: newUint64(1713330442), // 2024-04-17 05:07:22 AM UTC
HaberTime: newUint64(1716962820), // 2024-05-29 06:07:00 AM UTC
Parlia: &ParliaConfig{ Parlia: &ParliaConfig{
Period: 3, Period: 3,
@@ -231,7 +229,6 @@ var (
FeynmanTime: newUint64(0), FeynmanTime: newUint64(0),
FeynmanFixTime: newUint64(0), FeynmanFixTime: newUint64(0),
CancunTime: newUint64(0), CancunTime: newUint64(0),
HaberTime: newUint64(0),
Parlia: &ParliaConfig{ Parlia: &ParliaConfig{
Period: 3, Period: 3,
@@ -270,7 +267,6 @@ var (
FeynmanTime: newUint64(0), FeynmanTime: newUint64(0),
FeynmanFixTime: newUint64(0), FeynmanFixTime: newUint64(0),
CancunTime: newUint64(0), CancunTime: newUint64(0),
Parlia: &ParliaConfig{ Parlia: &ParliaConfig{
Period: 3, Period: 3,
Epoch: 200, Epoch: 200,
@@ -508,7 +504,6 @@ type ChainConfig struct {
FeynmanTime *uint64 `json:"feynmanTime,omitempty"` // Feynman switch time (nil = no fork, 0 = already activated) FeynmanTime *uint64 `json:"feynmanTime,omitempty"` // Feynman switch time (nil = no fork, 0 = already activated)
FeynmanFixTime *uint64 `json:"feynmanFixTime,omitempty"` // FeynmanFix switch time (nil = no fork, 0 = already activated) FeynmanFixTime *uint64 `json:"feynmanFixTime,omitempty"` // FeynmanFix switch time (nil = no fork, 0 = already activated)
CancunTime *uint64 `json:"cancunTime,omitempty"` // Cancun switch time (nil = no fork, 0 = already on cancun) CancunTime *uint64 `json:"cancunTime,omitempty"` // Cancun switch time (nil = no fork, 0 = already on cancun)
HaberTime *uint64 `json:"haberTime,omitempty"` // Haber switch time (nil = no fork, 0 = already on haber)
PragueTime *uint64 `json:"pragueTime,omitempty"` // Prague switch time (nil = no fork, 0 = already on prague) PragueTime *uint64 `json:"pragueTime,omitempty"` // Prague switch time (nil = no fork, 0 = already on prague)
VerkleTime *uint64 `json:"verkleTime,omitempty"` // Verkle switch time (nil = no fork, 0 = already on verkle) VerkleTime *uint64 `json:"verkleTime,omitempty"` // Verkle switch time (nil = no fork, 0 = already on verkle)
@@ -614,12 +609,7 @@ func (c *ChainConfig) String() string {
CancunTime = big.NewInt(0).SetUint64(*c.CancunTime) CancunTime = big.NewInt(0).SetUint64(*c.CancunTime)
} }
var HaberTime *big.Int return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, CatalystBlock: %v, London: %v, ArrowGlacier: %v, MergeFork:%v, Euler: %v, Gibbs: %v, Nano: %v, Moran: %v, Planck: %v,Luban: %v, Plato: %v, Hertz: %v, Hertzfix: %v, ShanghaiTime: %v, KeplerTime: %v, FeynmanTime: %v, FeynmanFixTime: %v, CancunTime: %v, Engine: %v}",
if c.HaberTime != nil {
HaberTime = big.NewInt(0).SetUint64(*c.HaberTime)
}
return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, CatalystBlock: %v, London: %v, ArrowGlacier: %v, MergeFork:%v, Euler: %v, Gibbs: %v, Nano: %v, Moran: %v, Planck: %v,Luban: %v, Plato: %v, Hertz: %v, Hertzfix: %v, ShanghaiTime: %v, KeplerTime: %v, FeynmanTime: %v, FeynmanFixTime: %v, CancunTime: %v, HaberTime: %v, Engine: %v}",
c.ChainID, c.ChainID,
c.HomesteadBlock, c.HomesteadBlock,
c.DAOForkBlock, c.DAOForkBlock,
@@ -656,7 +646,6 @@ func (c *ChainConfig) String() string {
FeynmanTime, FeynmanTime,
FeynmanFixTime, FeynmanFixTime,
CancunTime, CancunTime,
HaberTime,
engine, engine,
) )
} }
@@ -924,11 +913,6 @@ func (c *ChainConfig) IsCancun(num *big.Int, time uint64) bool {
return c.IsLondon(num) && isTimestampForked(c.CancunTime, time) return c.IsLondon(num) && isTimestampForked(c.CancunTime, time)
} }
// IsHaber returns whether time is either equal to the Haber fork time or greater.
func (c *ChainConfig) IsHaber(num *big.Int, time uint64) bool {
return c.IsLondon(num) && isTimestampForked(c.HaberTime, time)
}
// IsPrague returns whether num is either equal to the Prague fork time or greater. // IsPrague returns whether num is either equal to the Prague fork time or greater.
func (c *ChainConfig) IsPrague(num *big.Int, time uint64) bool { func (c *ChainConfig) IsPrague(num *big.Int, time uint64) bool {
return c.IsLondon(num) && isTimestampForked(c.PragueTime, time) return c.IsLondon(num) && isTimestampForked(c.PragueTime, time)
@@ -992,7 +976,6 @@ func (c *ChainConfig) CheckConfigForkOrder() error {
{name: "feynmanTime", timestamp: c.FeynmanTime}, {name: "feynmanTime", timestamp: c.FeynmanTime},
{name: "feynmanFixTime", timestamp: c.FeynmanFixTime}, {name: "feynmanFixTime", timestamp: c.FeynmanFixTime},
{name: "cancunTime", timestamp: c.CancunTime}, {name: "cancunTime", timestamp: c.CancunTime},
{name: "haberTime", timestamp: c.HaberTime},
{name: "pragueTime", timestamp: c.PragueTime, optional: true}, {name: "pragueTime", timestamp: c.PragueTime, optional: true},
{name: "verkleTime", timestamp: c.VerkleTime, optional: true}, {name: "verkleTime", timestamp: c.VerkleTime, optional: true},
} { } {
@@ -1322,8 +1305,8 @@ type Rules struct {
IsPlato bool IsPlato bool
IsHertz bool IsHertz bool
IsHertzfix bool IsHertzfix bool
IsShanghai, IsKepler, IsFeynman, IsCancun, IsHaber bool IsShanghai, IsKepler, IsFeynman, IsCancun, IsPrague bool
IsPrague, IsVerkle bool IsVerkle bool
} }
// Rules ensures c's ChainID is not nil. // Rules ensures c's ChainID is not nil.
@@ -1358,7 +1341,6 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules
IsKepler: c.IsKepler(num, timestamp), IsKepler: c.IsKepler(num, timestamp),
IsFeynman: c.IsFeynman(num, timestamp), IsFeynman: c.IsFeynman(num, timestamp),
IsCancun: c.IsCancun(num, timestamp), IsCancun: c.IsCancun(num, timestamp),
IsHaber: c.IsHaber(num, timestamp),
IsPrague: c.IsPrague(num, timestamp), IsPrague: c.IsPrague(num, timestamp),
IsVerkle: c.IsVerkle(num, timestamp), IsVerkle: c.IsVerkle(num, timestamp),
} }

View File

@@ -170,8 +170,6 @@ const (
Bls12381MapG1Gas uint64 = 5500 // Gas price for BLS12-381 mapping field element to G1 operation Bls12381MapG1Gas uint64 = 5500 // Gas price for BLS12-381 mapping field element to G1 operation
Bls12381MapG2Gas uint64 = 110000 // Gas price for BLS12-381 mapping field element to G2 operation Bls12381MapG2Gas uint64 = 110000 // Gas price for BLS12-381 mapping field element to G2 operation
P256VerifyGas uint64 = 3450 // secp256r1 elliptic curve signature verifier gas price
// The Refund Quotient is the cap on how much of the used gas can be refunded. Before EIP-3529, // The Refund Quotient is the cap on how much of the used gas can be refunded. Before EIP-3529,
// up to half the consumed gas could be refunded. Redefined as 1/5th in EIP-3529 // up to half the consumed gas could be refunded. Redefined as 1/5th in EIP-3529
RefundQuotient uint64 = 2 RefundQuotient uint64 = 2

View File

@@ -23,7 +23,7 @@ import (
const ( const (
VersionMajor = 1 // Major version component of the current release VersionMajor = 1 // Major version component of the current release
VersionMinor = 4 // Minor version component of the current release VersionMinor = 4 // Minor version component of the current release
VersionPatch = 8 // Patch version component of the current release VersionPatch = 7 // Patch version component of the current release
VersionMeta = "" // Version metadata to append to the version string VersionMeta = "" // Version metadata to append to the version string
) )

View File

@@ -21,14 +21,22 @@ import (
"bytes" "bytes"
"errors" "errors"
"fmt" "fmt"
"time"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/trie/trienode" "github.com/ethereum/go-ethereum/trie/trienode"
"github.com/ethereum/go-ethereum/triedb/database" "github.com/ethereum/go-ethereum/triedb/database"
) )
var (
trieGetTimer = metrics.NewRegisteredTimer("trie/get/time", nil)
trieReaderGetTimer = metrics.NewRegisteredTimer("trie/reader/get/time", nil)
trieReaderTotalTimer = metrics.NewRegisteredTimer("trie/reader/total/time", nil)
)
// Trie is a Merkle Patricia Trie. Use New to create a trie that sits on // Trie is a Merkle Patricia Trie. Use New to create a trie that sits on
// top of a database. Whenever trie performs a commit operation, the generated // top of a database. Whenever trie performs a commit operation, the generated
// nodes will be gathered and returned in a set. Once the trie is committed, // nodes will be gathered and returned in a set. Once the trie is committed,
@@ -146,6 +154,10 @@ func (t *Trie) Get(key []byte) ([]byte, error) {
if t.committed { if t.committed {
return nil, ErrCommitted return nil, ErrCommitted
} }
if metrics.EnabledExpensive {
start := time.Now()
defer func() { trieGetTimer.UpdateSince(start) }()
}
value, newroot, didResolve, err := t.get(t.root, keybytesToHex(key), 0) value, newroot, didResolve, err := t.get(t.root, keybytesToHex(key), 0)
if err == nil && didResolve { if err == nil && didResolve {
t.root = newroot t.root = newroot
@@ -178,7 +190,11 @@ func (t *Trie) get(origNode node, key []byte, pos int) (value []byte, newnode no
} }
return value, n, didResolve, err return value, n, didResolve, err
case hashNode: case hashNode:
start := time.Now()
child, err := t.resolveAndTrack(n, key[:pos]) child, err := t.resolveAndTrack(n, key[:pos])
if metrics.EnabledExpensive {
trieReaderGetTimer.UpdateSince(start)
}
if err != nil { if err != nil {
return nil, n, true, err return nil, n, true, err
} }
@@ -586,6 +602,10 @@ func (t *Trie) resolve(n node, prefix []byte) (node, error) {
// node's original value. The rlp-encoded blob is preferred to be loaded from // node's original value. The rlp-encoded blob is preferred to be loaded from
// database because it's easy to decode node while complex to encode node to blob. // database because it's easy to decode node while complex to encode node to blob.
func (t *Trie) resolveAndTrack(n hashNode, prefix []byte) (node, error) { func (t *Trie) resolveAndTrack(n hashNode, prefix []byte) (node, error) {
if metrics.EnabledExpensive {
start := time.Now()
defer func() { trieReaderTotalTimer.UpdateSince(start) }()
}
blob, err := t.reader.node(prefix, common.BytesToHash(n)) blob, err := t.reader.node(prefix, common.BytesToHash(n))
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -19,6 +19,7 @@ package pathdb
import ( import (
"fmt" "fmt"
"sync" "sync"
"time"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
@@ -104,6 +105,8 @@ func (dl *diffLayer) node(owner common.Hash, path []byte, hash common.Hash, dept
dl.lock.RLock() dl.lock.RLock()
defer dl.lock.RUnlock() defer dl.lock.RUnlock()
start := time.Now()
// If the trie node is known locally, return it // If the trie node is known locally, return it
subset, ok := dl.nodes[owner] subset, ok := dl.nodes[owner]
if ok { if ok {
@@ -114,14 +117,18 @@ func (dl *diffLayer) node(owner common.Hash, path []byte, hash common.Hash, dept
if n.Hash != hash { if n.Hash != hash {
dirtyFalseMeter.Mark(1) dirtyFalseMeter.Mark(1)
log.Error("Unexpected trie node in diff layer", "owner", owner, "path", path, "expect", hash, "got", n.Hash) log.Error("Unexpected trie node in diff layer", "owner", owner, "path", path, "expect", hash, "got", n.Hash)
pathGetDiffLayerTimer.UpdateSince(start)
return nil, newUnexpectedNodeError("diff", hash, n.Hash, owner, path, n.Blob) return nil, newUnexpectedNodeError("diff", hash, n.Hash, owner, path, n.Blob)
} }
dirtyHitMeter.Mark(1) dirtyHitMeter.Mark(1)
dirtyNodeHitDepthHist.Update(int64(depth)) dirtyNodeHitDepthHist.Update(int64(depth))
dirtyReadMeter.Mark(int64(len(n.Blob))) dirtyReadMeter.Mark(int64(len(n.Blob)))
pathGetDiffLayerTimer.UpdateSince(start)
return n.Blob, nil return n.Blob, nil
} }
} }
pathGetDiffLayerTimer.UpdateSince(start)
// Trie node unknown to this layer, resolve from parent // Trie node unknown to this layer, resolve from parent
if diff, ok := dl.parent.(*diffLayer); ok { if diff, ok := dl.parent.(*diffLayer); ok {
return diff.node(owner, path, hash, depth+1) return diff.node(owner, path, hash, depth+1)

View File

@@ -20,6 +20,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"sync" "sync"
"time"
"github.com/VictoriaMetrics/fastcache" "github.com/VictoriaMetrics/fastcache"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@@ -27,6 +28,7 @@ import (
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/trie/trienode" "github.com/ethereum/go-ethereum/trie/trienode"
"github.com/ethereum/go-ethereum/trie/triestate" "github.com/ethereum/go-ethereum/trie/triestate"
"golang.org/x/crypto/sha3" "golang.org/x/crypto/sha3"
@@ -155,6 +157,10 @@ func (dl *diskLayer) markStale() {
func (dl *diskLayer) Node(owner common.Hash, path []byte, hash common.Hash) ([]byte, error) { func (dl *diskLayer) Node(owner common.Hash, path []byte, hash common.Hash) ([]byte, error) {
dl.lock.RLock() dl.lock.RLock()
defer dl.lock.RUnlock() defer dl.lock.RUnlock()
if metrics.EnabledExpensive {
start := time.Now()
defer func() { pathGetDiskLayerTimer.UpdateSince(start) }()
}
if dl.stale { if dl.stale {
return nil, errSnapshotStale return nil, errSnapshotStale

View File

@@ -47,4 +47,7 @@ var (
historyBuildTimeMeter = metrics.NewRegisteredTimer("pathdb/history/time", nil) historyBuildTimeMeter = metrics.NewRegisteredTimer("pathdb/history/time", nil)
historyDataBytesMeter = metrics.NewRegisteredMeter("pathdb/history/bytes/data", nil) historyDataBytesMeter = metrics.NewRegisteredMeter("pathdb/history/bytes/data", nil)
historyIndexBytesMeter = metrics.NewRegisteredMeter("pathdb/history/bytes/index", nil) historyIndexBytesMeter = metrics.NewRegisteredMeter("pathdb/history/bytes/index", nil)
pathGetDiffLayerTimer = metrics.NewRegisteredTimer("pathdb/get/difflayer/time", nil)
pathGetDiskLayerTimer = metrics.NewRegisteredTimer("pathdb/get/disklayer/time", nil)
) )