mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 03:30:37 +00:00
Remove Parlia (#7306)
Pre-requisite: https://github.com/ledgerwatch/erigon-lib/pull/969
This commit is contained in:
parent
2a356babfe
commit
96bb5d544b
@ -57,8 +57,6 @@ System Requirements
|
||||
|
||||
* Gnosis Chain Archive: 370GB (January 2023).
|
||||
|
||||
* BSC Archive: 7TB. BSC Full: 1TB. (April 2022).
|
||||
|
||||
* Polygon Mainnet Archive: 5TB. Polygon Mumbai Archive: 1TB. (April 2022).
|
||||
|
||||
SSD or NVMe. Do not recommend HDD - on HDD Erigon will always stay N blocks behind chain tip, but not fall behind.
|
||||
@ -97,7 +95,7 @@ make erigon
|
||||
./build/bin/erigon
|
||||
```
|
||||
|
||||
Default `--snapshots` for `mainnet`, `goerli`, `gnosis`, `bsc`. Other networks now have default `--snapshots=false`.
|
||||
Default `--snapshots` for `mainnet`, `goerli`, `gnosis`, `chiado`. Other networks now have default `--snapshots=false`.
|
||||
Increase
|
||||
download speed by flag `--torrent.download.rate=20mb`. <code>🔬 See [Downloader docs](./cmd/downloader/readme.md)</code>
|
||||
|
||||
|
@ -16,6 +16,12 @@ import (
|
||||
|
||||
"github.com/c2h5oh/datasize"
|
||||
"github.com/holiman/uint256"
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
"golang.org/x/exp/slices"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
|
||||
"github.com/ledgerwatch/erigon-lib/chain"
|
||||
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
||||
"github.com/ledgerwatch/erigon-lib/common/datadir"
|
||||
@ -39,18 +45,6 @@ import (
|
||||
txpool2 "github.com/ledgerwatch/erigon-lib/txpool"
|
||||
"github.com/ledgerwatch/erigon-lib/txpool/txpooluitl"
|
||||
types2 "github.com/ledgerwatch/erigon-lib/types"
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
"golang.org/x/exp/slices"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
|
||||
"github.com/ledgerwatch/erigon/core/systemcontracts"
|
||||
|
||||
"github.com/ledgerwatch/erigon/core/state/historyv2read"
|
||||
"github.com/ledgerwatch/erigon/core/types/accounts"
|
||||
"github.com/ledgerwatch/erigon/p2p/dnsdisc"
|
||||
"github.com/ledgerwatch/erigon/p2p/enode"
|
||||
|
||||
"github.com/ledgerwatch/erigon/cmd/erigon-el/eth1"
|
||||
stages3 "github.com/ledgerwatch/erigon/cmd/erigon-el/stages"
|
||||
@ -62,12 +56,14 @@ import (
|
||||
"github.com/ledgerwatch/erigon/consensus/bor"
|
||||
"github.com/ledgerwatch/erigon/consensus/clique"
|
||||
"github.com/ledgerwatch/erigon/consensus/ethash"
|
||||
"github.com/ledgerwatch/erigon/consensus/parlia"
|
||||
"github.com/ledgerwatch/erigon/consensus/serenity"
|
||||
"github.com/ledgerwatch/erigon/core"
|
||||
"github.com/ledgerwatch/erigon/core/rawdb"
|
||||
"github.com/ledgerwatch/erigon/core/state/historyv2read"
|
||||
"github.com/ledgerwatch/erigon/core/state/temporal"
|
||||
"github.com/ledgerwatch/erigon/core/systemcontracts"
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
"github.com/ledgerwatch/erigon/core/types/accounts"
|
||||
"github.com/ledgerwatch/erigon/core/vm"
|
||||
"github.com/ledgerwatch/erigon/crypto"
|
||||
"github.com/ledgerwatch/erigon/eth/ethconfig"
|
||||
@ -80,6 +76,8 @@ import (
|
||||
"github.com/ledgerwatch/erigon/ethstats"
|
||||
"github.com/ledgerwatch/erigon/node"
|
||||
"github.com/ledgerwatch/erigon/p2p"
|
||||
"github.com/ledgerwatch/erigon/p2p/dnsdisc"
|
||||
"github.com/ledgerwatch/erigon/p2p/enode"
|
||||
"github.com/ledgerwatch/erigon/params"
|
||||
"github.com/ledgerwatch/erigon/rpc"
|
||||
"github.com/ledgerwatch/erigon/turbo/engineapi"
|
||||
@ -208,11 +206,6 @@ func NewBackend(stack *node.Node, config *ethconfig.Config, logger log.Logger) (
|
||||
|
||||
log.Info("Initialised chain configuration", "config", chainConfig, "genesis", genesis.Hash())
|
||||
|
||||
// Apply special hacks for BSC params
|
||||
if chainConfig.Parlia != nil {
|
||||
params.ApplyBinanceSmartChainParams()
|
||||
}
|
||||
|
||||
if err := chainKv.Update(context.Background(), func(tx kv.RwTx) error {
|
||||
if err = stagedsync.UpdateMetrics(tx); err != nil {
|
||||
return err
|
||||
@ -420,8 +413,6 @@ func NewBackend(stack *node.Node, config *ethconfig.Config, logger log.Logger) (
|
||||
} else if chainConfig.Aura != nil {
|
||||
config.Aura.Etherbase = config.Miner.Etherbase
|
||||
consensusConfig = &config.Aura
|
||||
} else if chainConfig.Parlia != nil {
|
||||
consensusConfig = &config.Parlia
|
||||
} else if chainConfig.Bor != nil {
|
||||
consensusConfig = &config.Bor
|
||||
} else {
|
||||
@ -729,25 +720,6 @@ func (s *Ethereum) StartMining(ctx context.Context, db kv.RwDB, mining *stagedsy
|
||||
})
|
||||
}
|
||||
|
||||
var prl *parlia.Parlia
|
||||
if p, ok := s.engine.(*parlia.Parlia); ok {
|
||||
prl = p
|
||||
} else if cl, ok := s.engine.(*serenity.Serenity); ok {
|
||||
if p, ok := cl.InnerEngine().(*parlia.Parlia); ok {
|
||||
prl = p
|
||||
}
|
||||
}
|
||||
if prl != nil {
|
||||
if cfg.SigKey == nil {
|
||||
log.Error("Etherbase account unavailable locally", "err", err)
|
||||
return fmt.Errorf("signer missing: %w", err)
|
||||
}
|
||||
|
||||
prl.Authorize(eb, func(validator libcommon.Address, payload []byte, chainId *big.Int) ([]byte, error) {
|
||||
return crypto.Sign(payload, cfg.SigKey)
|
||||
})
|
||||
}
|
||||
|
||||
var borcfg *bor.Bor
|
||||
if b, ok := s.engine.(*bor.Bor); ok {
|
||||
borcfg = b
|
||||
|
@ -1292,11 +1292,6 @@ func newDomains(ctx context.Context, db kv.RwDB, stepSize uint64, mode libstate.
|
||||
}
|
||||
//log.Info("Initialised chain configuration", "config", chainConfig)
|
||||
|
||||
// Apply special hacks for BSC params
|
||||
if chainConfig.Parlia != nil {
|
||||
params.ApplyBinanceSmartChainParams()
|
||||
}
|
||||
|
||||
var batchSize datasize.ByteSize
|
||||
must(batchSize.UnmarshalText([]byte(batchSizeStr)))
|
||||
|
||||
@ -1332,11 +1327,6 @@ func newSync(ctx context.Context, db kv.RwDB, miningConfig *params.MiningConfig)
|
||||
}
|
||||
//log.Info("Initialised chain configuration", "config", chainConfig)
|
||||
|
||||
// Apply special hacks for BSC params
|
||||
if chainConfig.Parlia != nil {
|
||||
params.ApplyBinanceSmartChainParams()
|
||||
}
|
||||
|
||||
var batchSize datasize.ByteSize
|
||||
must(batchSize.UnmarshalText([]byte(batchSizeStr)))
|
||||
|
||||
@ -1445,8 +1435,6 @@ func initConsensusEngine(cc *chain2.Config, datadir string, db kv.RwDB) (engine
|
||||
} else if cc.Aura != nil {
|
||||
config.Aura.Etherbase = config.Miner.Etherbase
|
||||
consensusConfig = &config.Aura
|
||||
} else if cc.Parlia != nil {
|
||||
consensusConfig = &config.Parlia
|
||||
} else if cc.Bor != nil {
|
||||
consensusConfig = &config.Bor
|
||||
} else {
|
||||
|
@ -607,8 +607,6 @@ func initConsensusEngine(cc *chain2.Config, snapshots *snapshotsync.RoSnapshots)
|
||||
} else if cc.Aura != nil {
|
||||
config.Aura.Etherbase = config.Miner.Etherbase
|
||||
consensusConfig = &config.Aura
|
||||
} else if cc.Parlia != nil {
|
||||
consensusConfig = &config.Parlia
|
||||
} else if cc.Bor != nil {
|
||||
consensusConfig = &config.Bor
|
||||
} else {
|
||||
|
@ -46,10 +46,6 @@ var rootCmd = &cobra.Command{
|
||||
utils.Fatalf("provided genesis.json chain configuration is invalid: expected chainId to be %v, got %v",
|
||||
chainConfig.ChainID.String(), genesis.Config.ChainID.String())
|
||||
}
|
||||
// Apply special hacks for BSC params
|
||||
if chainConfig.Parlia != nil {
|
||||
params.ApplyBinanceSmartChainParams()
|
||||
}
|
||||
|
||||
if chaindata == "" {
|
||||
chaindata = filepath.Join(datadirCli, "chaindata")
|
||||
|
@ -5,11 +5,12 @@ import (
|
||||
"math/big"
|
||||
"sync"
|
||||
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/ledgerwatch/erigon-lib/chain"
|
||||
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
||||
"github.com/ledgerwatch/erigon-lib/kv"
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/ledgerwatch/erigon/cmd/state/exec22"
|
||||
"github.com/ledgerwatch/erigon/consensus"
|
||||
@ -17,7 +18,6 @@ import (
|
||||
"github.com/ledgerwatch/erigon/core"
|
||||
"github.com/ledgerwatch/erigon/core/rawdb"
|
||||
"github.com/ledgerwatch/erigon/core/state"
|
||||
"github.com/ledgerwatch/erigon/core/systemcontracts"
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
"github.com/ledgerwatch/erigon/core/vm"
|
||||
"github.com/ledgerwatch/erigon/core/vm/evmtypes"
|
||||
@ -42,8 +42,6 @@ type Worker struct {
|
||||
genesis *types.Genesis
|
||||
resultCh *exec22.ResultsQueue
|
||||
chain ChainReader
|
||||
isPoSA bool
|
||||
posa consensus.PoSA
|
||||
|
||||
callTracer *CallTracer
|
||||
taskGasPool *core.GasPool
|
||||
@ -83,7 +81,6 @@ func NewWorker(lock sync.Locker, ctx context.Context, background bool, chainDb k
|
||||
|
||||
w.ibs = state.New(w.stateReader)
|
||||
|
||||
w.posa, w.isPoSA = engine.(consensus.PoSA)
|
||||
return w
|
||||
}
|
||||
|
||||
@ -154,9 +151,6 @@ func (rw *Worker) RunTxTaskNoLock(txTask *exec22.TxTask) {
|
||||
} else if txTask.TxIndex == -1 {
|
||||
// Block initialisation
|
||||
//fmt.Printf("txNum=%d, blockNum=%d, initialisation of the block\n", txTask.TxNum, txTask.BlockNum)
|
||||
if rw.isPoSA {
|
||||
systemcontracts.UpgradeBuildInSystemContract(rw.chainConfig, header.Number, ibs)
|
||||
}
|
||||
syscall := func(contract libcommon.Address, data []byte) ([]byte, error) {
|
||||
return core.SysCallContract(contract, data, *rw.chainConfig, ibs, header, rw.engine, false /* constCall */, nil /*excessDataGas*/)
|
||||
}
|
||||
@ -184,14 +178,6 @@ func (rw *Worker) RunTxTaskNoLock(txTask *exec22.TxTask) {
|
||||
}
|
||||
} else {
|
||||
//fmt.Printf("txNum=%d, blockNum=%d, txIndex=%d\n", txTask.TxNum, txTask.BlockNum, txTask.TxIndex)
|
||||
if rw.isPoSA {
|
||||
if isSystemTx, err := rw.posa.IsSystemTransaction(txTask.Tx, header); err != nil {
|
||||
panic(err)
|
||||
} else if isSystemTx {
|
||||
//fmt.Printf("System tx\n")
|
||||
return
|
||||
}
|
||||
}
|
||||
txHash := txTask.Tx.Hash()
|
||||
rw.taskGasPool.Reset(txTask.Tx.GetGas())
|
||||
rw.callTracer.Reset()
|
||||
|
@ -7,13 +7,14 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/RoaringBitmap/roaring/roaring64"
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
|
||||
"github.com/ledgerwatch/erigon-lib/chain"
|
||||
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
||||
"github.com/ledgerwatch/erigon-lib/common/length"
|
||||
"github.com/ledgerwatch/erigon-lib/etl"
|
||||
"github.com/ledgerwatch/erigon-lib/kv"
|
||||
libstate "github.com/ledgerwatch/erigon-lib/state"
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
|
||||
"github.com/ledgerwatch/erigon/cmd/state/exec22"
|
||||
"github.com/ledgerwatch/erigon/common"
|
||||
@ -21,7 +22,6 @@ import (
|
||||
"github.com/ledgerwatch/erigon/consensus/misc"
|
||||
"github.com/ledgerwatch/erigon/core"
|
||||
"github.com/ledgerwatch/erigon/core/state"
|
||||
"github.com/ledgerwatch/erigon/core/systemcontracts"
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
"github.com/ledgerwatch/erigon/core/types/accounts"
|
||||
"github.com/ledgerwatch/erigon/core/vm"
|
||||
@ -231,8 +231,6 @@ type ReconWorker struct {
|
||||
logger log.Logger
|
||||
genesis *types.Genesis
|
||||
chain ChainReader
|
||||
isPoSA bool
|
||||
posa consensus.PoSA
|
||||
|
||||
evm *vm.EVM
|
||||
ibs *state.IntraBlockState
|
||||
@ -258,7 +256,6 @@ func NewReconWorker(lock sync.Locker, ctx context.Context, rs *state.ReconState,
|
||||
}
|
||||
rw.chain = NewChainReader(chainConfig, chainTx, blockReader)
|
||||
rw.ibs = state.New(rw.stateReader)
|
||||
rw.posa, rw.isPoSA = engine.(consensus.PoSA)
|
||||
return rw
|
||||
}
|
||||
|
||||
@ -325,24 +322,12 @@ func (rw *ReconWorker) runTxTask(txTask *exec22.TxTask) error {
|
||||
}
|
||||
} else if txTask.TxIndex == -1 {
|
||||
// Block initialisation
|
||||
if rw.isPoSA {
|
||||
systemcontracts.UpgradeBuildInSystemContract(rw.chainConfig, txTask.Header.Number, ibs)
|
||||
}
|
||||
syscall := func(contract libcommon.Address, data []byte) ([]byte, error) {
|
||||
return core.SysCallContract(contract, data, *rw.chainConfig, ibs, txTask.Header, rw.engine, false /* constCall */, nil /*excessDataGas*/)
|
||||
}
|
||||
|
||||
rw.engine.Initialize(rw.chainConfig, rw.chain, txTask.Header, ibs, txTask.Txs, txTask.Uncles, syscall)
|
||||
} else {
|
||||
if rw.isPoSA {
|
||||
if isSystemTx, err := rw.posa.IsSystemTransaction(txTask.Tx, txTask.Header); err != nil {
|
||||
if _, readError := rw.stateReader.ReadError(); !readError {
|
||||
return err
|
||||
}
|
||||
} else if isSystemTx {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
gp := new(core.GasPool).AddGas(txTask.Tx.GetGas())
|
||||
vmConfig := vm.Config{NoReceipts: true, SkipAnalysis: txTask.SkipAnalysis}
|
||||
ibs.Prepare(txTask.Tx.Hash(), txTask.BlockHash, txTask.TxIndex)
|
||||
|
@ -129,7 +129,7 @@ var (
|
||||
}
|
||||
SnapshotFlag = cli.BoolFlag{
|
||||
Name: "snapshots",
|
||||
Usage: `Default: use snapshots "true" for BSC, Mainnet and Goerli. use snapshots "false" in all other cases`,
|
||||
Usage: `Default: use snapshots "true" for Mainnet, Goerli, Gnosis Chain and Chiado. use snapshots "false" in all other cases`,
|
||||
Value: true,
|
||||
}
|
||||
ExternalConsensusFlag = cli.BoolFlag{
|
||||
@ -1346,10 +1346,6 @@ func setAuRa(ctx *cli.Context, cfg *chain.AuRaConfig, datadir string) {
|
||||
cfg.DBPath = filepath.Join(datadir, "aura")
|
||||
}
|
||||
|
||||
func setParlia(ctx *cli.Context, cfg *chain.ParliaConfig, datadir string) {
|
||||
cfg.DBPath = filepath.Join(datadir, "parlia")
|
||||
}
|
||||
|
||||
func setBorConfig(ctx *cli.Context, cfg *ethconfig.Config) {
|
||||
cfg.HeimdallURL = ctx.String(HeimdallURLFlag.Name)
|
||||
cfg.WithoutHeimdall = ctx.Bool(WithoutHeimdallFlag.Name)
|
||||
@ -1505,7 +1501,6 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *nodecfg.Config, cfg *ethconfig.C
|
||||
setEthash(ctx, nodeConfig.Dirs.DataDir, cfg)
|
||||
setClique(ctx, &cfg.Clique, nodeConfig.Dirs.DataDir)
|
||||
setAuRa(ctx, &cfg.Aura, nodeConfig.Dirs.DataDir)
|
||||
setParlia(ctx, &cfg.Parlia, nodeConfig.Dirs.DataDir)
|
||||
setMiner(ctx, &cfg.Miner)
|
||||
setWhitelist(ctx, cfg)
|
||||
setBorConfig(ctx, cfg)
|
||||
|
@ -18,7 +18,6 @@
|
||||
package consensus
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
|
||||
"github.com/ledgerwatch/erigon-lib/chain"
|
||||
@ -152,23 +151,3 @@ type PoW interface {
|
||||
// Hashrate returns the current mining hashrate of a PoW consensus engine.
|
||||
Hashrate() float64
|
||||
}
|
||||
|
||||
var (
|
||||
SystemAddress = libcommon.HexToAddress("0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE")
|
||||
)
|
||||
|
||||
type PoSA interface {
|
||||
Engine
|
||||
|
||||
IsSystemTransaction(tx types.Transaction, header *types.Header) (bool, error)
|
||||
IsSystemContract(to *libcommon.Address) bool
|
||||
EnoughDistance(chain ChainReader, header *types.Header) bool
|
||||
IsLocalBlock(header *types.Header) bool
|
||||
AllowLightProcess(chain ChainReader, currentHeader *types.Header) bool
|
||||
}
|
||||
|
||||
type AsyncEngine interface {
|
||||
Engine
|
||||
|
||||
WithExecutionContext(context.Context) AsyncEngine
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,89 +0,0 @@
|
||||
// Copyright 2017 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package parlia
|
||||
|
||||
import (
|
||||
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
||||
|
||||
"github.com/ledgerwatch/erigon/consensus"
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
"github.com/ledgerwatch/erigon/rpc"
|
||||
)
|
||||
|
||||
// API is a user facing RPC API to allow query snapshot and validators
|
||||
type API struct {
|
||||
chain consensus.ChainHeaderReader
|
||||
parlia *Parlia
|
||||
}
|
||||
|
||||
// GetSnapshot retrieves the state snapshot at a given block.
|
||||
func (api *API) GetSnapshot(number *rpc.BlockNumber) (*Snapshot, error) {
|
||||
// Retrieve the requested block number (or current if none requested)
|
||||
var header *types.Header
|
||||
if number == nil || *number == rpc.LatestBlockNumber {
|
||||
header = api.chain.CurrentHeader()
|
||||
} else {
|
||||
header = api.chain.GetHeaderByNumber(uint64(number.Int64()))
|
||||
}
|
||||
// Ensure we have an actually valid block and return its snapshot
|
||||
if header == nil {
|
||||
return nil, errUnknownBlock
|
||||
}
|
||||
return api.parlia.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil, false /* verify */)
|
||||
}
|
||||
|
||||
// GetSnapshotAtHash retrieves the state snapshot at a given block.
|
||||
func (api *API) GetSnapshotAtHash(hash libcommon.Hash) (*Snapshot, error) {
|
||||
header := api.chain.GetHeaderByHash(hash)
|
||||
if header == nil {
|
||||
return nil, errUnknownBlock
|
||||
}
|
||||
return api.parlia.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil, false /* verify */)
|
||||
}
|
||||
|
||||
// GetValidators retrieves the list of validators at the specified block.
|
||||
func (api *API) GetValidators(number *rpc.BlockNumber) ([]libcommon.Address, error) {
|
||||
// Retrieve the requested block number (or current if none requested)
|
||||
var header *types.Header
|
||||
if number == nil || *number == rpc.LatestBlockNumber {
|
||||
header = api.chain.CurrentHeader()
|
||||
} else {
|
||||
header = api.chain.GetHeaderByNumber(uint64(number.Int64()))
|
||||
}
|
||||
// Ensure we have an actually valid block and return the validators from its snapshot
|
||||
if header == nil {
|
||||
return nil, errUnknownBlock
|
||||
}
|
||||
snap, err := api.parlia.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil, false /* verify */)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return snap.validators(), nil
|
||||
}
|
||||
|
||||
// GetValidatorsAtHash retrieves the list of validators at the specified block.
|
||||
func (api *API) GetValidatorsAtHash(hash libcommon.Hash) ([]libcommon.Address, error) {
|
||||
header := api.chain.GetHeaderByHash(hash)
|
||||
if header == nil {
|
||||
return nil, errUnknownBlock
|
||||
}
|
||||
snap, err := api.parlia.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil, false /* verify */)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return snap.validators(), nil
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,45 +0,0 @@
|
||||
package parlia
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/ledgerwatch/erigon/consensus"
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
)
|
||||
|
||||
const (
|
||||
wiggleTimeBeforeFork = 500 * time.Millisecond // Random delay (per signer) to allow concurrent signers
|
||||
fixedBackOffTimeBeforeFork = 200 * time.Millisecond
|
||||
)
|
||||
|
||||
func (p *Parlia) delayForRamanujanFork(snap *Snapshot, header *types.Header) time.Duration {
|
||||
delay := time.Until(time.Unix(int64(header.Time), 0)) // nolint: gosimple
|
||||
if p.chainConfig.IsRamanujan(header.Number.Uint64()) {
|
||||
return delay
|
||||
}
|
||||
if header.Difficulty.Cmp(diffNoTurn) == 0 {
|
||||
// It's not our turn explicitly to sign, delay it a bit
|
||||
wiggle := time.Duration(len(snap.Validators)/2+1) * wiggleTimeBeforeFork
|
||||
delay += fixedBackOffTimeBeforeFork + time.Duration(rand.Int63n(int64(wiggle))) // nolint
|
||||
}
|
||||
return delay
|
||||
}
|
||||
|
||||
func (p *Parlia) blockTimeForRamanujanFork(snap *Snapshot, header, parent *types.Header) uint64 {
|
||||
blockTime := parent.Time + p.config.Period
|
||||
if p.chainConfig.IsRamanujan(header.Number.Uint64()) {
|
||||
blockTime = blockTime + backOffTime(snap, p.val)
|
||||
}
|
||||
return blockTime
|
||||
}
|
||||
|
||||
func (p *Parlia) blockTimeVerifyForRamanujanFork(snap *Snapshot, header, parent *types.Header) error {
|
||||
if p.chainConfig.IsRamanujan(header.Number.Uint64()) {
|
||||
if header.Time < parent.Time+p.config.Period+backOffTime(snap, header.Coinbase) {
|
||||
return fmt.Errorf("header %d, time %d, now %d, period: %d, backof: %d, %w", header.Number.Uint64(), header.Time, time.Now().Unix(), p.config.Period, backOffTime(snap, header.Coinbase), consensus.ErrFutureBlock)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
@ -1,346 +0,0 @@
|
||||
// Copyright 2017 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package parlia
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"sort"
|
||||
|
||||
"github.com/hashicorp/golang-lru/v2"
|
||||
"github.com/ledgerwatch/erigon-lib/chain"
|
||||
"github.com/ledgerwatch/erigon-lib/common"
|
||||
"github.com/ledgerwatch/erigon-lib/common/hexutility"
|
||||
"github.com/ledgerwatch/erigon-lib/kv"
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
|
||||
"github.com/ledgerwatch/erigon/consensus"
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
)
|
||||
|
||||
// Snapshot is the state of the validatorSet at a given point.
|
||||
type Snapshot struct {
|
||||
config *chain.ParliaConfig // Consensus engine parameters to fine tune behavior
|
||||
sigCache *lru.ARCCache[common.Hash, common.Address] // Cache of recent block signatures to speed up ecrecover
|
||||
|
||||
Number uint64 `json:"number"` // Block number where the snapshot was created
|
||||
Hash common.Hash `json:"hash"` // Block hash where the snapshot was created
|
||||
Validators map[common.Address]struct{} `json:"validators"` // Set of authorized validators at this moment
|
||||
Recents map[uint64]common.Address `json:"recents"` // Set of recent validators for spam protections
|
||||
RecentForkHashes map[uint64]string `json:"recent_fork_hashes"` // Set of recent forkHash
|
||||
}
|
||||
|
||||
// newSnapshot creates a new snapshot with the specified startup parameters. This
|
||||
// method does not initialize the set of recent validators, so only ever use it for
|
||||
// the genesis block.
|
||||
func newSnapshot(
|
||||
config *chain.ParliaConfig,
|
||||
sigCache *lru.ARCCache[common.Hash, common.Address],
|
||||
number uint64,
|
||||
hash common.Hash,
|
||||
validators []common.Address,
|
||||
) *Snapshot {
|
||||
snap := &Snapshot{
|
||||
config: config,
|
||||
sigCache: sigCache,
|
||||
Number: number,
|
||||
Hash: hash,
|
||||
Recents: make(map[uint64]common.Address),
|
||||
RecentForkHashes: make(map[uint64]string),
|
||||
Validators: make(map[common.Address]struct{}),
|
||||
}
|
||||
for _, v := range validators {
|
||||
snap.Validators[v] = struct{}{}
|
||||
}
|
||||
return snap
|
||||
}
|
||||
|
||||
// validatorsAscending implements the sort interface to allow sorting a list of addresses
|
||||
type validatorsAscending []common.Address
|
||||
|
||||
func (s validatorsAscending) Len() int { return len(s) }
|
||||
func (s validatorsAscending) Less(i, j int) bool { return bytes.Compare(s[i][:], s[j][:]) < 0 }
|
||||
func (s validatorsAscending) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
// SnapshotFullKey = SnapshotBucket + num (uint64 big endian) + hash
|
||||
func SnapshotFullKey(number uint64, hash common.Hash) []byte {
|
||||
return append(hexutility.EncodeTs(number), hash.Bytes()...)
|
||||
}
|
||||
|
||||
var ErrNoSnapsnot = fmt.Errorf("no parlia snapshot")
|
||||
|
||||
// loadSnapshot loads an existing snapshot from the database.
|
||||
func loadSnapshot(config *chain.ParliaConfig, sigCache *lru.ARCCache[common.Hash, common.Address], db kv.RwDB, num uint64, hash common.Hash) (*Snapshot, error) {
|
||||
tx, err := db.BeginRo(context.Background())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
blob, err := tx.GetOne(kv.ParliaSnapshot, SnapshotFullKey(num, hash))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(blob) == 0 {
|
||||
return nil, ErrNoSnapsnot
|
||||
}
|
||||
snap := new(Snapshot)
|
||||
if err := json.Unmarshal(blob, snap); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
snap.config = config
|
||||
snap.sigCache = sigCache
|
||||
return snap, nil
|
||||
}
|
||||
|
||||
// store inserts the snapshot into the database.
|
||||
func (s *Snapshot) store(db kv.RwDB) error {
|
||||
blob, err := json.Marshal(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return db.UpdateNosync(context.Background(), func(tx kv.RwTx) error {
|
||||
return tx.Put(kv.ParliaSnapshot, SnapshotFullKey(s.Number, s.Hash), blob)
|
||||
})
|
||||
}
|
||||
|
||||
// copy creates a deep copy of the snapshot
|
||||
func (s *Snapshot) copy() *Snapshot {
|
||||
cpy := &Snapshot{
|
||||
config: s.config,
|
||||
sigCache: s.sigCache,
|
||||
Number: s.Number,
|
||||
Hash: s.Hash,
|
||||
Validators: make(map[common.Address]struct{}),
|
||||
Recents: make(map[uint64]common.Address),
|
||||
RecentForkHashes: make(map[uint64]string),
|
||||
}
|
||||
|
||||
for v := range s.Validators {
|
||||
cpy.Validators[v] = struct{}{}
|
||||
}
|
||||
for block, v := range s.Recents {
|
||||
cpy.Recents[block] = v
|
||||
}
|
||||
for block, id := range s.RecentForkHashes {
|
||||
cpy.RecentForkHashes[block] = id
|
||||
}
|
||||
return cpy
|
||||
}
|
||||
|
||||
// nolint
|
||||
func (s *Snapshot) isMajorityFork(forkHash string) bool {
|
||||
ally := 0
|
||||
for _, h := range s.RecentForkHashes {
|
||||
if h == forkHash {
|
||||
ally++
|
||||
}
|
||||
}
|
||||
return ally > len(s.RecentForkHashes)/2
|
||||
}
|
||||
|
||||
func (s *Snapshot) apply(headers []*types.Header, chain consensus.ChainHeaderReader, parents []*types.Header, chainId *big.Int, doLog bool) (*Snapshot, error) {
|
||||
// Allow passing in no headers for cleaner code
|
||||
if len(headers) == 0 {
|
||||
return s, nil
|
||||
}
|
||||
// Sanity check that the headers can be applied
|
||||
for i := 0; i < len(headers)-1; i++ {
|
||||
if headers[i+1].Number.Uint64() != headers[i].Number.Uint64()+1 {
|
||||
return nil, errOutOfRangeChain
|
||||
}
|
||||
if !bytes.Equal(headers[i+1].ParentHash.Bytes(), headers[i].Hash().Bytes()) {
|
||||
return nil, errBlockHashInconsistent
|
||||
}
|
||||
}
|
||||
if headers[0].Number.Uint64() != s.Number+1 {
|
||||
return nil, errOutOfRangeChain
|
||||
}
|
||||
if !bytes.Equal(headers[0].ParentHash.Bytes(), s.Hash.Bytes()) {
|
||||
return nil, errBlockHashInconsistent
|
||||
}
|
||||
// Iterate through the headers and create a new snapshot
|
||||
snap := s.copy()
|
||||
|
||||
for _, header := range headers {
|
||||
number := header.Number.Uint64()
|
||||
if doLog && number%100_000 == 0 {
|
||||
log.Info("[parlia] snapshots build, recover from headers", "block", number)
|
||||
}
|
||||
// Delete the oldest validator from the recent list to allow it signing again
|
||||
if limit := uint64(len(snap.Validators)/2 + 1); number >= limit {
|
||||
delete(snap.Recents, number-limit)
|
||||
}
|
||||
if limit := uint64(len(snap.Validators)); number >= limit {
|
||||
delete(snap.RecentForkHashes, number-limit)
|
||||
}
|
||||
// Resolve the authorization key and check against signers
|
||||
validator, err := ecrecover(header, s.sigCache, chainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Disabling this validation due to issues with BEP-131 looks like is breaks the property that used to allow Erigon to sync Parlia without knowning the contract state
|
||||
// Further investigation is required
|
||||
/*
|
||||
if _, ok := snap.Validators[validator]; !ok {
|
||||
return nil, errUnauthorizedValidator
|
||||
}
|
||||
*/
|
||||
for _, recent := range snap.Recents {
|
||||
if recent == validator {
|
||||
return nil, errRecentlySigned
|
||||
}
|
||||
}
|
||||
snap.Recents[number] = validator
|
||||
// change validator set
|
||||
if number > 0 && number%s.config.Epoch == uint64(len(snap.Validators)/2) {
|
||||
checkpointHeader := FindAncientHeader(header, uint64(len(snap.Validators)/2), chain, parents)
|
||||
if checkpointHeader == nil {
|
||||
return nil, consensus.ErrUnknownAncestor
|
||||
}
|
||||
|
||||
validatorBytes := checkpointHeader.Extra[extraVanity : len(checkpointHeader.Extra)-extraSeal]
|
||||
// get validators from headers and use that for new validator set
|
||||
newValArr, err := ParseValidators(validatorBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newVals := make(map[common.Address]struct{}, len(newValArr))
|
||||
for _, val := range newValArr {
|
||||
newVals[val] = struct{}{}
|
||||
}
|
||||
oldLimit := len(snap.Validators)/2 + 1
|
||||
newLimit := len(newVals)/2 + 1
|
||||
if newLimit < oldLimit {
|
||||
for i := 0; i < oldLimit-newLimit; i++ {
|
||||
delete(snap.Recents, number-uint64(newLimit)-uint64(i))
|
||||
}
|
||||
}
|
||||
oldLimit = len(snap.Validators)
|
||||
newLimit = len(newVals)
|
||||
if newLimit < oldLimit {
|
||||
for i := 0; i < oldLimit-newLimit; i++ {
|
||||
delete(snap.RecentForkHashes, number-uint64(newLimit)-uint64(i))
|
||||
}
|
||||
}
|
||||
snap.Validators = newVals
|
||||
}
|
||||
snap.RecentForkHashes[number] = hex.EncodeToString(header.Extra[extraVanity-nextForkHashSize : extraVanity])
|
||||
}
|
||||
snap.Number += uint64(len(headers))
|
||||
snap.Hash = headers[len(headers)-1].Hash()
|
||||
return snap, nil
|
||||
}
|
||||
|
||||
// validators retrieves the list of validators in ascending order.
|
||||
func (s *Snapshot) validators() []common.Address {
|
||||
validators := make([]common.Address, 0, len(s.Validators))
|
||||
for v := range s.Validators {
|
||||
validators = append(validators, v)
|
||||
}
|
||||
sort.Sort(validatorsAscending(validators))
|
||||
return validators
|
||||
}
|
||||
|
||||
// inturn returns if a validator at a given block height is in-turn or not.
|
||||
func (s *Snapshot) inturn(validator common.Address) bool {
|
||||
validators := s.validators()
|
||||
offset := (s.Number + 1) % uint64(len(validators))
|
||||
return validators[offset] == validator
|
||||
}
|
||||
|
||||
func (s *Snapshot) enoughDistance(validator common.Address, header *types.Header) bool {
|
||||
idx := s.indexOfVal(validator)
|
||||
if idx < 0 {
|
||||
return true
|
||||
}
|
||||
validatorNum := int64(len(s.validators()))
|
||||
if validatorNum == 1 {
|
||||
return true
|
||||
}
|
||||
if validator == header.Coinbase {
|
||||
return false
|
||||
}
|
||||
offset := (int64(s.Number) + 1) % validatorNum
|
||||
if int64(idx) >= offset {
|
||||
return int64(idx)-offset >= validatorNum-2
|
||||
} else {
|
||||
return validatorNum+int64(idx)-offset >= validatorNum-2
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Snapshot) indexOfVal(validator common.Address) int {
|
||||
validators := s.validators()
|
||||
for idx, val := range validators {
|
||||
if val == validator {
|
||||
return idx
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (s *Snapshot) supposeValidator() common.Address {
|
||||
validators := s.validators()
|
||||
index := (s.Number + 1) % uint64(len(validators))
|
||||
return validators[index]
|
||||
}
|
||||
|
||||
func ParseValidators(validatorsBytes []byte) ([]common.Address, error) {
|
||||
if len(validatorsBytes)%validatorBytesLength != 0 {
|
||||
return nil, errors.New("invalid validators bytes")
|
||||
}
|
||||
n := len(validatorsBytes) / validatorBytesLength
|
||||
result := make([]common.Address, n)
|
||||
for i := 0; i < n; i++ {
|
||||
address := make([]byte, validatorBytesLength)
|
||||
copy(address, validatorsBytes[i*validatorBytesLength:(i+1)*validatorBytesLength])
|
||||
result[i] = common.BytesToAddress(address)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func FindAncientHeader(header *types.Header, ite uint64, chain consensus.ChainHeaderReader, candidateParents []*types.Header) *types.Header {
|
||||
ancient := header
|
||||
for i := uint64(1); i <= ite; i++ {
|
||||
parentHash := ancient.ParentHash
|
||||
parentHeight := ancient.Number.Uint64() - 1
|
||||
found := false
|
||||
if len(candidateParents) > 0 {
|
||||
index := sort.Search(len(candidateParents), func(i int) bool {
|
||||
return candidateParents[i].Number.Uint64() >= parentHeight
|
||||
})
|
||||
if index < len(candidateParents) && candidateParents[index].Number.Uint64() == parentHeight &&
|
||||
candidateParents[index].Hash() == parentHash {
|
||||
ancient = candidateParents[index]
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
ancient = chain.GetHeader(parentHash, parentHeight)
|
||||
found = true
|
||||
}
|
||||
if ancient == nil || !found {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return ancient
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package parlia
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math/rand"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestValidatorSetSort(t *testing.T) {
|
||||
size := 100
|
||||
validators := make([]libcommon.Address, size)
|
||||
for i := 0; i < size; i++ {
|
||||
validators[i] = randomAddress()
|
||||
}
|
||||
sort.Sort(validatorsAscending(validators))
|
||||
for i := 0; i < size-1; i++ {
|
||||
assert.True(t, bytes.Compare(validators[i][:], validators[i+1][:]) < 0)
|
||||
}
|
||||
}
|
||||
|
||||
func randomAddress() libcommon.Address {
|
||||
addrBytes := make([]byte, 20)
|
||||
rand.Read(addrBytes)
|
||||
return libcommon.BytesToAddress(addrBytes)
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
package parlia
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
|
||||
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
||||
)
|
||||
|
||||
func backOffTime(snap *Snapshot, val libcommon.Address) uint64 {
|
||||
if snap.inturn(val) {
|
||||
return 0
|
||||
} else {
|
||||
idx := snap.indexOfVal(val)
|
||||
if idx < 0 {
|
||||
// The backOffTime does not matter when a validator is not authorized.
|
||||
return 0
|
||||
}
|
||||
s := rand.NewSource(int64(snap.Number))
|
||||
r := rand.New(s) // nolint: gosec
|
||||
n := len(snap.Validators)
|
||||
backOffSteps := make([]uint64, 0, n)
|
||||
for idx := uint64(0); idx < uint64(n); idx++ {
|
||||
backOffSteps = append(backOffSteps, idx)
|
||||
}
|
||||
r.Shuffle(n, func(i, j int) {
|
||||
backOffSteps[i], backOffSteps[j] = backOffSteps[j], backOffSteps[i]
|
||||
})
|
||||
delay := initialBackOffTime + backOffSteps[idx]*wiggleTime
|
||||
return delay
|
||||
}
|
||||
}
|
@ -22,16 +22,12 @@ import (
|
||||
"math/big"
|
||||
"time"
|
||||
|
||||
"github.com/ledgerwatch/erigon-lib/chain"
|
||||
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
||||
metrics2 "github.com/VictoriaMetrics/metrics"
|
||||
"golang.org/x/crypto/sha3"
|
||||
"golang.org/x/exp/slices"
|
||||
|
||||
"github.com/ledgerwatch/erigon/core/systemcontracts"
|
||||
"github.com/ledgerwatch/erigon/core/vm/evmtypes"
|
||||
"github.com/ledgerwatch/erigon/rlp"
|
||||
|
||||
metrics2 "github.com/VictoriaMetrics/metrics"
|
||||
"github.com/ledgerwatch/erigon-lib/chain"
|
||||
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
||||
|
||||
"github.com/ledgerwatch/erigon/common/math"
|
||||
"github.com/ledgerwatch/erigon/common/u256"
|
||||
@ -40,6 +36,8 @@ import (
|
||||
"github.com/ledgerwatch/erigon/core/state"
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
"github.com/ledgerwatch/erigon/core/vm"
|
||||
"github.com/ledgerwatch/erigon/core/vm/evmtypes"
|
||||
"github.com/ledgerwatch/erigon/rlp"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -72,154 +70,6 @@ type EphemeralExecResult struct {
|
||||
StateSyncReceipt *types.Receipt `json:"-"`
|
||||
}
|
||||
|
||||
func ExecuteBlockEphemerallyForBSC(
|
||||
chainConfig *chain.Config,
|
||||
vmConfig *vm.Config,
|
||||
blockHashFunc func(n uint64) libcommon.Hash,
|
||||
engine consensus.Engine, block *types.Block,
|
||||
stateReader state.StateReader, stateWriter state.WriterWithChangeSets,
|
||||
chainReader consensus.ChainHeaderReader, getTracer func(txIndex int, txHash libcommon.Hash) (vm.EVMLogger, error),
|
||||
) (*EphemeralExecResult, error) {
|
||||
defer BlockExecutionTimer.UpdateDuration(time.Now())
|
||||
block.Uncles()
|
||||
ibs := state.New(stateReader)
|
||||
header := block.Header()
|
||||
usedGas := new(uint64)
|
||||
gp := new(GasPool)
|
||||
gp.AddGas(block.GasLimit())
|
||||
|
||||
var (
|
||||
rejectedTxs []*RejectedTx
|
||||
includedTxs types.Transactions
|
||||
receipts types.Receipts
|
||||
)
|
||||
|
||||
var excessDataGas *big.Int
|
||||
ph := chainReader.GetHeaderByHash(block.ParentHash())
|
||||
if ph != nil {
|
||||
excessDataGas = ph.ExcessDataGas
|
||||
}
|
||||
if !vmConfig.ReadOnly {
|
||||
if err := InitializeBlockExecution(engine, chainReader, block.Header(), block.Transactions(), block.Uncles(), chainConfig, ibs, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(block.Number()) == 0 {
|
||||
misc.ApplyDAOHardFork(ibs)
|
||||
}
|
||||
systemcontracts.UpgradeBuildInSystemContract(chainConfig, header.Number, ibs)
|
||||
noop := state.NewNoopWriter()
|
||||
posa, isPoSA := engine.(consensus.PoSA)
|
||||
//fmt.Printf("====txs processing start: %d====\n", block.NumberU64())
|
||||
for i, tx := range block.Transactions() {
|
||||
if isPoSA {
|
||||
if isSystemTx, err := posa.IsSystemTransaction(tx, block.Header()); err != nil {
|
||||
return nil, err
|
||||
} else if isSystemTx {
|
||||
continue
|
||||
}
|
||||
}
|
||||
ibs.Prepare(tx.Hash(), block.Hash(), i)
|
||||
writeTrace := false
|
||||
if vmConfig.Debug && vmConfig.Tracer == nil {
|
||||
tracer, err := getTracer(i, tx.Hash())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not obtain tracer: %w", err)
|
||||
}
|
||||
vmConfig.Tracer = tracer
|
||||
writeTrace = true
|
||||
}
|
||||
|
||||
receipt, _, err := ApplyTransaction(chainConfig, blockHashFunc, engine, nil, gp, ibs, noop, header, tx, usedGas, *vmConfig, excessDataGas)
|
||||
if writeTrace {
|
||||
if ftracer, ok := vmConfig.Tracer.(vm.FlushableTracer); ok {
|
||||
ftracer.Flush(tx)
|
||||
}
|
||||
|
||||
vmConfig.Tracer = nil
|
||||
}
|
||||
if err != nil {
|
||||
if !vmConfig.StatelessExec {
|
||||
return nil, fmt.Errorf("could not apply tx %d from block %d [%v]: %w", i, block.NumberU64(), tx.Hash().Hex(), err)
|
||||
}
|
||||
rejectedTxs = append(rejectedTxs, &RejectedTx{i, err.Error()})
|
||||
} else {
|
||||
includedTxs = append(includedTxs, tx)
|
||||
if !vmConfig.NoReceipts {
|
||||
receipts = append(receipts, receipt)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var newBlock *types.Block
|
||||
var receiptSha libcommon.Hash
|
||||
if !vmConfig.ReadOnly {
|
||||
// We're doing this hack for BSC to avoid changing consensus interfaces a lot. BSC modifies txs and receipts by appending
|
||||
// system transactions, and they increase used gas and write cumulative gas to system receipts, that's why we need
|
||||
// to deduct system gas before. This line is equal to "blockGas-systemGas", but since we don't know how much gas is
|
||||
// used by system transactions we just override. Of course, we write used by block gas back. It also always true
|
||||
// that used gas by block is always equal to original's block header gas, and it's checked by receipts root verification
|
||||
// otherwise it causes block verification error.
|
||||
header.GasUsed = *usedGas
|
||||
syscall := func(contract libcommon.Address, data []byte) ([]byte, error) {
|
||||
return SysCallContract(contract, data, *chainConfig, ibs, header, engine, false /* constCall */, excessDataGas)
|
||||
}
|
||||
outTxs, outReceipts, err := engine.Finalize(chainConfig, header, ibs, block.Transactions(), block.Uncles(), receipts, block.Withdrawals(), chainReader, syscall)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
*usedGas = header.GasUsed
|
||||
|
||||
// We need repack this block because transactions and receipts might be changed by consensus, and
|
||||
// it won't pass receipts hash or bloom verification
|
||||
newBlock = types.NewBlock(block.Header(), outTxs, block.Uncles(), outReceipts, block.Withdrawals())
|
||||
// Update receipts
|
||||
if !vmConfig.NoReceipts {
|
||||
receipts = outReceipts
|
||||
}
|
||||
receiptSha = newBlock.ReceiptHash()
|
||||
} else {
|
||||
newBlock = block
|
||||
receiptSha = types.DeriveSha(receipts)
|
||||
}
|
||||
|
||||
if chainConfig.IsByzantium(header.Number.Uint64()) && !vmConfig.NoReceipts {
|
||||
if !vmConfig.StatelessExec && receiptSha != block.ReceiptHash() {
|
||||
return nil, fmt.Errorf("mismatched receipt headers for block %d (%s != %s)", block.NumberU64(), receiptSha.Hex(), block.ReceiptHash().Hex())
|
||||
}
|
||||
}
|
||||
if !vmConfig.StatelessExec && newBlock.GasUsed() != header.GasUsed {
|
||||
return nil, fmt.Errorf("gas used by execution: %d, in header: %d, in new Block: %v", *usedGas, header.GasUsed, newBlock.GasUsed())
|
||||
}
|
||||
|
||||
var bloom types.Bloom
|
||||
if !vmConfig.NoReceipts {
|
||||
bloom = newBlock.Bloom()
|
||||
if !vmConfig.StatelessExec && bloom != header.Bloom {
|
||||
return nil, fmt.Errorf("bloom computed by execution: %x, in header: %x", bloom, header.Bloom)
|
||||
}
|
||||
}
|
||||
|
||||
if err := ibs.CommitBlock(chainConfig.Rules(header.Number.Uint64(), header.Time), stateWriter); err != nil {
|
||||
return nil, fmt.Errorf("committing block %d failed: %w", header.Number.Uint64(), err)
|
||||
} else if err := stateWriter.WriteChangeSets(); err != nil {
|
||||
return nil, fmt.Errorf("writing changesets for block %d failed: %w", header.Number.Uint64(), err)
|
||||
}
|
||||
|
||||
execRs := &EphemeralExecResult{
|
||||
TxRoot: types.DeriveSha(includedTxs),
|
||||
ReceiptRoot: receiptSha,
|
||||
Bloom: bloom,
|
||||
Receipts: receipts,
|
||||
Difficulty: (*math.HexOrDecimal256)(block.Header().Difficulty),
|
||||
GasUsed: math.HexOrDecimal64(*usedGas),
|
||||
Rejected: rejectedTxs,
|
||||
}
|
||||
|
||||
return execRs, nil
|
||||
}
|
||||
|
||||
// ExecuteBlockEphemerally runs a block from provided stateReader and
|
||||
// writes the result to the provided stateWriter
|
||||
func ExecuteBlockEphemerally(
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/holiman/uint256"
|
||||
|
||||
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
||||
"github.com/ledgerwatch/erigon-lib/txpool"
|
||||
types2 "github.com/ledgerwatch/erigon-lib/types"
|
||||
@ -27,8 +28,6 @@ import (
|
||||
"github.com/ledgerwatch/erigon/common"
|
||||
cmath "github.com/ledgerwatch/erigon/common/math"
|
||||
"github.com/ledgerwatch/erigon/common/u256"
|
||||
"github.com/ledgerwatch/erigon/consensus"
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
"github.com/ledgerwatch/erigon/core/vm"
|
||||
"github.com/ledgerwatch/erigon/core/vm/evmtypes"
|
||||
"github.com/ledgerwatch/erigon/crypto"
|
||||
@ -73,8 +72,7 @@ type StateTransition struct {
|
||||
sharedBuyGas *uint256.Int
|
||||
sharedBuyGasBalance *uint256.Int
|
||||
|
||||
isParlia bool
|
||||
isBor bool
|
||||
isBor bool
|
||||
}
|
||||
|
||||
// Message represents a message sent to a contract.
|
||||
@ -151,7 +149,6 @@ func IntrinsicGas(data []byte, accessList types2.AccessList, isContractCreation
|
||||
|
||||
// NewStateTransition initialises and returns a new state transition object.
|
||||
func NewStateTransition(evm vm.VMInterface, msg Message, gp *GasPool) *StateTransition {
|
||||
isParlia := evm.ChainConfig().Parlia != nil
|
||||
isBor := evm.ChainConfig().Bor != nil
|
||||
return &StateTransition{
|
||||
gp: gp,
|
||||
@ -167,8 +164,7 @@ func NewStateTransition(evm vm.VMInterface, msg Message, gp *GasPool) *StateTran
|
||||
sharedBuyGas: uint256.NewInt(0),
|
||||
sharedBuyGasBalance: uint256.NewInt(0),
|
||||
|
||||
isParlia: isParlia,
|
||||
isBor: isBor,
|
||||
isBor: isBor,
|
||||
}
|
||||
}
|
||||
|
||||
@ -316,12 +312,6 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*Executi
|
||||
// 5. there is no overflow when calculating intrinsic gas
|
||||
// 6. caller has enough balance to cover asset transfer for **topmost** call
|
||||
|
||||
// BSC always gave gas bailout due to system transactions that set 2^256/2 gas limit and
|
||||
// for Parlia consensus this flag should be always be set
|
||||
if st.isParlia {
|
||||
gasBailout = true
|
||||
}
|
||||
|
||||
// Check clauses 1-3 and 6, buy gas if everything is correct
|
||||
if err := st.preCheck(gasBailout); err != nil {
|
||||
return nil, err
|
||||
@ -340,17 +330,6 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*Executi
|
||||
vmConfig := st.evm.Config()
|
||||
isEIP3860 := vmConfig.HasEip3860(rules)
|
||||
|
||||
if rules.IsNano {
|
||||
for _, blackListAddr := range types.NanoBlackList {
|
||||
if blackListAddr == sender.Address() {
|
||||
return nil, fmt.Errorf("block blacklist account")
|
||||
}
|
||||
if msg.To() != nil && *msg.To() == blackListAddr {
|
||||
return nil, fmt.Errorf("block blacklist account")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check clauses 4-5, subtract intrinsic gas if everything is correct
|
||||
gas, err := IntrinsicGas(st.data, st.msg.AccessList(), contractCreation, rules.IsHomestead, rules.IsIstanbul, isEIP3860)
|
||||
if err != nil {
|
||||
@ -417,11 +396,7 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*Executi
|
||||
}
|
||||
amount := new(uint256.Int).SetUint64(st.gasUsed())
|
||||
amount.Mul(amount, effectiveTip) // gasUsed * effectiveTip = how much goes to the block producer (miner, validator)
|
||||
if st.isParlia {
|
||||
st.state.AddBalance(consensus.SystemAddress, amount)
|
||||
} else {
|
||||
st.state.AddBalance(st.evm.Context().Coinbase, amount)
|
||||
}
|
||||
st.state.AddBalance(st.evm.Context().Coinbase, amount)
|
||||
if !msg.IsFree() && rules.IsLondon && rules.IsEip1559FeeCollector {
|
||||
burntContractAddress := *st.evm.ChainConfig().Eip1559FeeCollector
|
||||
burnAmount := new(uint256.Int).Mul(new(uint256.Int).SetUint64(st.gasUsed()), st.evm.Context().BaseFee)
|
||||
|
@ -29,7 +29,6 @@ const (
|
||||
MimetypeDataWithValidator = "data/validator"
|
||||
MimetypeTypedData = "data/typed"
|
||||
MimetypeClique = "application/x-clique-header"
|
||||
MimetypeParlia = "application/x-parlia-header"
|
||||
MimetypeBor = "application/x-bor-header"
|
||||
MimetypeTextPlain = "text/plain"
|
||||
)
|
||||
|
@ -82,51 +82,6 @@ var PrecompiledContractsIstanbul = map[libcommon.Address]PrecompiledContract{
|
||||
libcommon.BytesToAddress([]byte{9}): &blake2F{},
|
||||
}
|
||||
|
||||
var PrecompiledContractsIstanbulForBSC = map[libcommon.Address]PrecompiledContract{
|
||||
libcommon.BytesToAddress([]byte{1}): &ecrecover{},
|
||||
libcommon.BytesToAddress([]byte{2}): &sha256hash{},
|
||||
libcommon.BytesToAddress([]byte{3}): &ripemd160hash{},
|
||||
libcommon.BytesToAddress([]byte{4}): &dataCopy{},
|
||||
libcommon.BytesToAddress([]byte{5}): &bigModExp{},
|
||||
libcommon.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
|
||||
libcommon.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
|
||||
libcommon.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
|
||||
libcommon.BytesToAddress([]byte{9}): &blake2F{},
|
||||
|
||||
libcommon.BytesToAddress([]byte{100}): &tmHeaderValidate{},
|
||||
libcommon.BytesToAddress([]byte{101}): &iavlMerkleProofValidate{},
|
||||
}
|
||||
|
||||
var PrecompiledContractsNano = map[libcommon.Address]PrecompiledContract{
|
||||
libcommon.BytesToAddress([]byte{1}): &ecrecover{},
|
||||
libcommon.BytesToAddress([]byte{2}): &sha256hash{},
|
||||
libcommon.BytesToAddress([]byte{3}): &ripemd160hash{},
|
||||
libcommon.BytesToAddress([]byte{4}): &dataCopy{},
|
||||
libcommon.BytesToAddress([]byte{5}): &bigModExp{},
|
||||
libcommon.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
|
||||
libcommon.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
|
||||
libcommon.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
|
||||
libcommon.BytesToAddress([]byte{9}): &blake2F{},
|
||||
|
||||
libcommon.BytesToAddress([]byte{100}): &tmHeaderValidateNano{},
|
||||
libcommon.BytesToAddress([]byte{101}): &iavlMerkleProofValidateNano{},
|
||||
}
|
||||
|
||||
var PrecompiledContractsIsMoran = map[libcommon.Address]PrecompiledContract{
|
||||
libcommon.BytesToAddress([]byte{1}): &ecrecover{},
|
||||
libcommon.BytesToAddress([]byte{2}): &sha256hash{},
|
||||
libcommon.BytesToAddress([]byte{3}): &ripemd160hash{},
|
||||
libcommon.BytesToAddress([]byte{4}): &dataCopy{},
|
||||
libcommon.BytesToAddress([]byte{5}): &bigModExp{},
|
||||
libcommon.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
|
||||
libcommon.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
|
||||
libcommon.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
|
||||
libcommon.BytesToAddress([]byte{9}): &blake2F{},
|
||||
|
||||
libcommon.BytesToAddress([]byte{100}): &tmHeaderValidate{},
|
||||
libcommon.BytesToAddress([]byte{101}): &iavlMerkleProofValidateMoran{},
|
||||
}
|
||||
|
||||
// PrecompiledContractsBerlin contains the default set of pre-compiled Ethereum
|
||||
// contracts used in the Berlin release.
|
||||
var PrecompiledContractsBerlin = map[libcommon.Address]PrecompiledContract{
|
||||
@ -156,13 +111,10 @@ var PrecompiledContractsBLS = map[libcommon.Address]PrecompiledContract{
|
||||
}
|
||||
|
||||
var (
|
||||
PrecompiledAddressesMoran []libcommon.Address
|
||||
PrecompiledAddressesNano []libcommon.Address
|
||||
PrecompiledAddressesBerlin []libcommon.Address
|
||||
PrecompiledAddressesIstanbul []libcommon.Address
|
||||
PrecompiledAddressesIstanbulForBSC []libcommon.Address
|
||||
PrecompiledAddressesByzantium []libcommon.Address
|
||||
PrecompiledAddressesHomestead []libcommon.Address
|
||||
PrecompiledAddressesBerlin []libcommon.Address
|
||||
PrecompiledAddressesIstanbul []libcommon.Address
|
||||
PrecompiledAddressesByzantium []libcommon.Address
|
||||
PrecompiledAddressesHomestead []libcommon.Address
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -175,33 +127,17 @@ func init() {
|
||||
for k := range PrecompiledContractsIstanbul {
|
||||
PrecompiledAddressesIstanbul = append(PrecompiledAddressesIstanbul, k)
|
||||
}
|
||||
for k := range PrecompiledContractsIstanbulForBSC {
|
||||
PrecompiledAddressesIstanbulForBSC = append(PrecompiledAddressesIstanbulForBSC, k)
|
||||
}
|
||||
for k := range PrecompiledContractsBerlin {
|
||||
PrecompiledAddressesBerlin = append(PrecompiledAddressesBerlin, k)
|
||||
}
|
||||
for k := range PrecompiledContractsNano {
|
||||
PrecompiledAddressesNano = append(PrecompiledAddressesNano, k)
|
||||
}
|
||||
for k := range PrecompiledContractsIsMoran {
|
||||
PrecompiledAddressesMoran = append(PrecompiledAddressesMoran, k)
|
||||
}
|
||||
}
|
||||
|
||||
// ActivePrecompiles returns the precompiles enabled with the current configuration.
|
||||
func ActivePrecompiles(rules *chain.Rules) []libcommon.Address {
|
||||
switch {
|
||||
case rules.IsMoran:
|
||||
return PrecompiledAddressesMoran
|
||||
case rules.IsNano:
|
||||
return PrecompiledAddressesNano
|
||||
case rules.IsBerlin:
|
||||
return PrecompiledAddressesBerlin
|
||||
case rules.IsIstanbul:
|
||||
if rules.IsParlia {
|
||||
return PrecompiledAddressesIstanbulForBSC
|
||||
}
|
||||
return PrecompiledAddressesIstanbul
|
||||
case rules.IsByzantium:
|
||||
return PrecompiledAddressesByzantium
|
||||
|
@ -1,242 +0,0 @@
|
||||
package vm
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"github.com/ledgerwatch/erigon/core/vm/lightclient/iavl"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
|
||||
"github.com/ledgerwatch/erigon/core/vm/lightclient"
|
||||
"github.com/ledgerwatch/erigon/params"
|
||||
"github.com/tendermint/tendermint/crypto/merkle"
|
||||
)
|
||||
|
||||
const (
|
||||
uint64TypeLength uint64 = 8
|
||||
precompileContractInputMetaDataLength uint64 = 32
|
||||
consensusStateLengthBytesLength uint64 = 32
|
||||
|
||||
tmHeaderValidateResultMetaDataLength uint64 = 32
|
||||
merkleProofValidateResultLength uint64 = 32
|
||||
)
|
||||
|
||||
// input:
|
||||
// consensus state length | consensus state | tendermint header |
|
||||
// 32 bytes | | |
|
||||
func decodeTendermintHeaderValidationInput(input []byte) (*lightclient.ConsensusState, *lightclient.Header, error) {
|
||||
csLen := binary.BigEndian.Uint64(input[consensusStateLengthBytesLength-uint64TypeLength : consensusStateLengthBytesLength])
|
||||
if uint64(len(input)) <= consensusStateLengthBytesLength+csLen {
|
||||
return nil, nil, fmt.Errorf("expected payload size %d, actual size: %d", consensusStateLengthBytesLength+csLen, len(input))
|
||||
}
|
||||
|
||||
cs, err := lightclient.DecodeConsensusState(input[consensusStateLengthBytesLength : consensusStateLengthBytesLength+csLen])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
header, err := lightclient.DecodeHeader(input[consensusStateLengthBytesLength+csLen:])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return &cs, header, nil
|
||||
}
|
||||
|
||||
// tmHeaderValidate implemented as a native contract.
|
||||
type tmHeaderValidate struct{}
|
||||
|
||||
func (c *tmHeaderValidate) RequiredGas(input []byte) uint64 {
|
||||
return params.TendermintHeaderValidateGas
|
||||
}
|
||||
|
||||
func (c *tmHeaderValidate) Run(input []byte) (result []byte, err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err = fmt.Errorf("internal error: %v", r)
|
||||
}
|
||||
}()
|
||||
|
||||
if uint64(len(input)) <= precompileContractInputMetaDataLength {
|
||||
return nil, fmt.Errorf("invalid input")
|
||||
}
|
||||
|
||||
payloadLength := binary.BigEndian.Uint64(input[precompileContractInputMetaDataLength-uint64TypeLength : precompileContractInputMetaDataLength])
|
||||
if uint64(len(input)) != payloadLength+precompileContractInputMetaDataLength {
|
||||
return nil, fmt.Errorf("invalid input: input size should be %d, actual the size is %d", payloadLength+precompileContractInputMetaDataLength, len(input))
|
||||
}
|
||||
|
||||
cs, header, err := decodeTendermintHeaderValidationInput(input[precompileContractInputMetaDataLength:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
validatorSetChanged, err := cs.ApplyHeader(header)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
consensusStateBytes, err := cs.EncodeConsensusState()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// result
|
||||
// | validatorSetChanged | empty | consensusStateBytesLength | new consensusState |
|
||||
// | 1 byte | 23 bytes | 8 bytes | |
|
||||
lengthBytes := make([]byte, tmHeaderValidateResultMetaDataLength)
|
||||
if validatorSetChanged {
|
||||
copy(lengthBytes[:1], []byte{0x01})
|
||||
}
|
||||
consensusStateBytesLength := uint64(len(consensusStateBytes))
|
||||
binary.BigEndian.PutUint64(lengthBytes[tmHeaderValidateResultMetaDataLength-uint64TypeLength:], consensusStateBytesLength)
|
||||
|
||||
result = append(lengthBytes, consensusStateBytes...)
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// iavlMerkleProofValidate implemented as a native contract.
|
||||
type iavlMerkleProofValidate struct {
|
||||
basicIavlMerkleProofValidate
|
||||
}
|
||||
|
||||
func (c *iavlMerkleProofValidate) RequiredGas(input []byte) uint64 {
|
||||
return params.IAVLMerkleProofValidateGas
|
||||
}
|
||||
|
||||
// input:
|
||||
// | payload length | payload |
|
||||
// | 32 bytes | |
|
||||
func (c *iavlMerkleProofValidate) Run(input []byte) (result []byte, err error) {
|
||||
return c.basicIavlMerkleProofValidate.Run(input)
|
||||
}
|
||||
|
||||
// tmHeaderValidate implemented as a native contract.
|
||||
type tmHeaderValidateNano struct{}
|
||||
|
||||
func (c *tmHeaderValidateNano) RequiredGas(input []byte) uint64 {
|
||||
return params.TendermintHeaderValidateGas
|
||||
}
|
||||
|
||||
func (c *tmHeaderValidateNano) Run(input []byte) (result []byte, err error) {
|
||||
return nil, fmt.Errorf("suspend")
|
||||
}
|
||||
|
||||
type iavlMerkleProofValidateNano struct{}
|
||||
|
||||
func (c *iavlMerkleProofValidateNano) RequiredGas(_ []byte) uint64 {
|
||||
return params.IAVLMerkleProofValidateGas
|
||||
}
|
||||
|
||||
func (c *iavlMerkleProofValidateNano) Run(_ []byte) (result []byte, err error) {
|
||||
return nil, fmt.Errorf("suspend")
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
type iavlMerkleProofValidateMoran struct {
|
||||
basicIavlMerkleProofValidate
|
||||
}
|
||||
|
||||
func (c *iavlMerkleProofValidateMoran) RequiredGas(_ []byte) uint64 {
|
||||
return params.IAVLMerkleProofValidateGas
|
||||
}
|
||||
|
||||
func (c *iavlMerkleProofValidateMoran) Run(input []byte) (result []byte, err error) {
|
||||
c.basicIavlMerkleProofValidate.verifiers = []merkle.ProofOpVerifier{
|
||||
forbiddenAbsenceOpVerifier,
|
||||
singleValueOpVerifier,
|
||||
multiStoreOpVerifier,
|
||||
forbiddenSimpleValueOpVerifier,
|
||||
}
|
||||
return c.basicIavlMerkleProofValidate.Run(input)
|
||||
}
|
||||
|
||||
type basicIavlMerkleProofValidate struct {
|
||||
verifiers []merkle.ProofOpVerifier
|
||||
}
|
||||
|
||||
func (c *basicIavlMerkleProofValidate) Run(input []byte) (result []byte, err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err = fmt.Errorf("internal error: %v", r)
|
||||
}
|
||||
}()
|
||||
|
||||
if uint64(len(input)) <= precompileContractInputMetaDataLength {
|
||||
return nil, fmt.Errorf("invalid input: input should include %d bytes payload length and payload", precompileContractInputMetaDataLength)
|
||||
}
|
||||
|
||||
payloadLength := binary.BigEndian.Uint64(input[precompileContractInputMetaDataLength-uint64TypeLength : precompileContractInputMetaDataLength])
|
||||
if uint64(len(input)) != payloadLength+precompileContractInputMetaDataLength {
|
||||
return nil, fmt.Errorf("invalid input: input size should be %d, actual the size is %d", payloadLength+precompileContractInputMetaDataLength, len(input))
|
||||
}
|
||||
|
||||
kvmp, err := lightclient.DecodeKeyValueMerkleProof(input[precompileContractInputMetaDataLength:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
kvmp.SetVerifiers(c.verifiers)
|
||||
valid := kvmp.Validate()
|
||||
if !valid {
|
||||
return nil, fmt.Errorf("invalid merkle proof")
|
||||
}
|
||||
|
||||
result = make([]byte, merkleProofValidateResultLength)
|
||||
binary.BigEndian.PutUint64(result[merkleProofValidateResultLength-uint64TypeLength:], 0x01)
|
||||
return result, nil
|
||||
}
|
||||
func forbiddenAbsenceOpVerifier(op merkle.ProofOperator) error {
|
||||
if op == nil {
|
||||
return nil
|
||||
}
|
||||
if _, ok := op.(iavl.IAVLAbsenceOp); ok {
|
||||
return cmn.NewError("absence proof suspend")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func forbiddenSimpleValueOpVerifier(op merkle.ProofOperator) error {
|
||||
if op == nil {
|
||||
return nil
|
||||
}
|
||||
if _, ok := op.(merkle.SimpleValueOp); ok {
|
||||
return cmn.NewError("simple value proof suspend")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func multiStoreOpVerifier(op merkle.ProofOperator) error {
|
||||
if op == nil {
|
||||
return nil
|
||||
}
|
||||
if mop, ok := op.(lightclient.MultiStoreProofOp); ok {
|
||||
storeNames := make(map[string]bool, len(mop.Proof.StoreInfos))
|
||||
for _, store := range mop.Proof.StoreInfos {
|
||||
if exist := storeNames[store.Name]; exist {
|
||||
return cmn.NewError("duplicated store")
|
||||
} else {
|
||||
storeNames[store.Name] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func singleValueOpVerifier(op merkle.ProofOperator) error {
|
||||
if op == nil {
|
||||
return nil
|
||||
}
|
||||
if valueOp, ok := op.(iavl.IAVLValueOp); ok {
|
||||
if len(valueOp.Proof.Leaves) != 1 {
|
||||
return cmn.NewError("range proof suspended")
|
||||
}
|
||||
for _, innerNode := range valueOp.Proof.LeftPath {
|
||||
if len(innerNode.Right) > 0 && len(innerNode.Left) > 0 {
|
||||
return cmn.NewError("both right and left hash exit!")
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -37,18 +37,10 @@ var emptyCodeHash = crypto.Keccak256Hash(nil)
|
||||
func (evm *EVM) precompile(addr libcommon.Address) (PrecompiledContract, bool) {
|
||||
var precompiles map[libcommon.Address]PrecompiledContract
|
||||
switch {
|
||||
case evm.chainRules.IsMoran:
|
||||
precompiles = PrecompiledContractsIsMoran
|
||||
case evm.chainRules.IsNano:
|
||||
precompiles = PrecompiledContractsNano
|
||||
case evm.chainRules.IsBerlin:
|
||||
precompiles = PrecompiledContractsBerlin
|
||||
case evm.chainRules.IsIstanbul:
|
||||
if evm.chainRules.IsParlia {
|
||||
precompiles = PrecompiledContractsIstanbulForBSC
|
||||
} else {
|
||||
precompiles = PrecompiledContractsIstanbul
|
||||
}
|
||||
precompiles = PrecompiledContractsIstanbul
|
||||
case evm.chainRules.IsByzantium:
|
||||
precompiles = PrecompiledContractsByzantium
|
||||
default:
|
||||
|
@ -32,6 +32,12 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/holiman/uint256"
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
"golang.org/x/exp/slices"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
|
||||
"github.com/ledgerwatch/erigon-lib/chain"
|
||||
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
||||
"github.com/ledgerwatch/erigon-lib/common/datadir"
|
||||
@ -54,18 +60,6 @@ import (
|
||||
txpool2 "github.com/ledgerwatch/erigon-lib/txpool"
|
||||
"github.com/ledgerwatch/erigon-lib/txpool/txpooluitl"
|
||||
types2 "github.com/ledgerwatch/erigon-lib/types"
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
"golang.org/x/exp/slices"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
|
||||
"github.com/ledgerwatch/erigon/core/systemcontracts"
|
||||
"github.com/ledgerwatch/erigon/p2p/enode"
|
||||
|
||||
"github.com/ledgerwatch/erigon/core/state/historyv2read"
|
||||
"github.com/ledgerwatch/erigon/core/state/temporal"
|
||||
"github.com/ledgerwatch/erigon/core/types/accounts"
|
||||
|
||||
"github.com/ledgerwatch/erigon/cl/clparams"
|
||||
clcore "github.com/ledgerwatch/erigon/cmd/erigon-cl/core"
|
||||
@ -80,11 +74,14 @@ import (
|
||||
"github.com/ledgerwatch/erigon/consensus/bor"
|
||||
"github.com/ledgerwatch/erigon/consensus/clique"
|
||||
"github.com/ledgerwatch/erigon/consensus/ethash"
|
||||
"github.com/ledgerwatch/erigon/consensus/parlia"
|
||||
"github.com/ledgerwatch/erigon/consensus/serenity"
|
||||
"github.com/ledgerwatch/erigon/core"
|
||||
"github.com/ledgerwatch/erigon/core/rawdb"
|
||||
"github.com/ledgerwatch/erigon/core/state/historyv2read"
|
||||
"github.com/ledgerwatch/erigon/core/state/temporal"
|
||||
"github.com/ledgerwatch/erigon/core/systemcontracts"
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
"github.com/ledgerwatch/erigon/core/types/accounts"
|
||||
"github.com/ledgerwatch/erigon/core/vm"
|
||||
"github.com/ledgerwatch/erigon/crypto"
|
||||
"github.com/ledgerwatch/erigon/eth/ethconfig"
|
||||
@ -98,6 +95,7 @@ import (
|
||||
"github.com/ledgerwatch/erigon/ethstats"
|
||||
"github.com/ledgerwatch/erigon/node"
|
||||
"github.com/ledgerwatch/erigon/p2p"
|
||||
"github.com/ledgerwatch/erigon/p2p/enode"
|
||||
"github.com/ledgerwatch/erigon/params"
|
||||
"github.com/ledgerwatch/erigon/rpc"
|
||||
"github.com/ledgerwatch/erigon/turbo/engineapi"
|
||||
@ -237,11 +235,6 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
||||
|
||||
log.Info("Initialised chain configuration", "config", chainConfig, "genesis", genesis.Hash())
|
||||
|
||||
// Apply special hacks for BSC params
|
||||
if chainConfig.Parlia != nil {
|
||||
params.ApplyBinanceSmartChainParams()
|
||||
}
|
||||
|
||||
if err := chainKv.Update(context.Background(), func(tx kv.RwTx) error {
|
||||
if err = stagedsync.UpdateMetrics(tx); err != nil {
|
||||
return err
|
||||
@ -446,8 +439,6 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
||||
} else if chainConfig.Aura != nil {
|
||||
config.Aura.Etherbase = config.Miner.Etherbase
|
||||
consensusConfig = &config.Aura
|
||||
} else if chainConfig.Parlia != nil {
|
||||
consensusConfig = &config.Parlia
|
||||
} else if chainConfig.Bor != nil {
|
||||
consensusConfig = &config.Bor
|
||||
} else {
|
||||
@ -838,25 +829,6 @@ func (s *Ethereum) StartMining(ctx context.Context, db kv.RwDB, mining *stagedsy
|
||||
})
|
||||
}
|
||||
|
||||
var prl *parlia.Parlia
|
||||
if p, ok := s.engine.(*parlia.Parlia); ok {
|
||||
prl = p
|
||||
} else if cl, ok := s.engine.(*serenity.Serenity); ok {
|
||||
if p, ok := cl.InnerEngine().(*parlia.Parlia); ok {
|
||||
prl = p
|
||||
}
|
||||
}
|
||||
if prl != nil {
|
||||
if cfg.SigKey == nil {
|
||||
log.Error("Etherbase account unavailable locally", "err", err)
|
||||
return fmt.Errorf("signer missing: %w", err)
|
||||
}
|
||||
|
||||
prl.Authorize(eb, func(validator libcommon.Address, payload []byte, chainId *big.Int) ([]byte, error) {
|
||||
return crypto.Sign(payload, cfg.SigKey)
|
||||
})
|
||||
}
|
||||
|
||||
var borcfg *bor.Bor
|
||||
if b, ok := s.engine.(*bor.Bor); ok {
|
||||
borcfg = b
|
||||
|
@ -206,7 +206,6 @@ type Config struct {
|
||||
|
||||
Clique params.ConsensusSnapshotConfig
|
||||
Aura chain.AuRaConfig
|
||||
Parlia chain.ParliaConfig
|
||||
Bor chain.BorConfig
|
||||
|
||||
// Transaction pool options
|
||||
|
@ -35,7 +35,6 @@ func (c Config) MarshalTOML() (interface{}, error) {
|
||||
Ethash ethashcfg.Config
|
||||
Clique params.ConsensusSnapshotConfig
|
||||
Aura chain.AuRaConfig
|
||||
Parlia chain.ParliaConfig
|
||||
TxPool DeprecatedTxPoolConfig
|
||||
GPO gaspricecfg.Config
|
||||
RPCGasCap uint64 `toml:",omitempty"`
|
||||
@ -60,7 +59,6 @@ func (c Config) MarshalTOML() (interface{}, error) {
|
||||
enc.Ethash = c.Ethash
|
||||
enc.Clique = c.Clique
|
||||
enc.Aura = c.Aura
|
||||
enc.Parlia = c.Parlia
|
||||
enc.TxPool = c.DeprecatedTxPool
|
||||
enc.GPO = c.GPO
|
||||
enc.RPCGasCap = c.RPCGasCap
|
||||
@ -88,7 +86,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
||||
Ethash *ethashcfg.Config
|
||||
Clique *params.ConsensusSnapshotConfig
|
||||
Aura *chain.AuRaConfig
|
||||
Parlia *chain.ParliaConfig
|
||||
TxPool *DeprecatedTxPoolConfig
|
||||
GPO *gaspricecfg.Config
|
||||
RPCGasCap *uint64 `toml:",omitempty"`
|
||||
@ -146,9 +143,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
||||
if dec.Aura != nil {
|
||||
c.Aura = *dec.Aura
|
||||
}
|
||||
if dec.Parlia != nil {
|
||||
c.Parlia = *dec.Parlia
|
||||
}
|
||||
if dec.TxPool != nil {
|
||||
c.DeprecatedTxPool = *dec.TxPool
|
||||
}
|
||||
|
@ -3,13 +3,12 @@ package ethconsensusconfig
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/ledgerwatch/erigon-lib/chain"
|
||||
"github.com/ledgerwatch/erigon-lib/kv"
|
||||
"github.com/ledgerwatch/erigon/consensus/ethash/ethashcfg"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
|
||||
"github.com/ledgerwatch/erigon-lib/chain"
|
||||
"github.com/ledgerwatch/erigon-lib/kv"
|
||||
|
||||
"github.com/ledgerwatch/erigon/consensus"
|
||||
"github.com/ledgerwatch/erigon/consensus/aura"
|
||||
"github.com/ledgerwatch/erigon/consensus/aura/consensusconfig"
|
||||
@ -21,7 +20,7 @@ import (
|
||||
"github.com/ledgerwatch/erigon/consensus/clique"
|
||||
"github.com/ledgerwatch/erigon/consensus/db"
|
||||
"github.com/ledgerwatch/erigon/consensus/ethash"
|
||||
"github.com/ledgerwatch/erigon/consensus/parlia"
|
||||
"github.com/ledgerwatch/erigon/consensus/ethash/ethashcfg"
|
||||
"github.com/ledgerwatch/erigon/consensus/serenity"
|
||||
"github.com/ledgerwatch/erigon/params"
|
||||
"github.com/ledgerwatch/erigon/turbo/snapshotsync"
|
||||
@ -70,13 +69,6 @@ func CreateConsensusEngine(chainConfig *chain.Config, config interface{}, notify
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
case *chain.ParliaConfig:
|
||||
if chainConfig.Parlia != nil {
|
||||
if consensusCfg.DBPath == "" {
|
||||
consensusCfg.DBPath = filepath.Join(datadir, "parlia")
|
||||
}
|
||||
eng = parlia.New(chainConfig, db.OpenDatabase(consensusCfg.DBPath, consensusCfg.InMemory, readonly), snapshots, chainDb[0])
|
||||
}
|
||||
case *chain.BorConfig:
|
||||
// If Matic bor consensus is requested, set it up
|
||||
// In order to pass the ethereum transaction tests, we need to set the burn contract which is in the bor config
|
||||
|
@ -463,9 +463,6 @@ func ExecV3(ctx context.Context,
|
||||
applyWorker.ResetTx(applyTx)
|
||||
}
|
||||
|
||||
_, isPoSa := cfg.engine.(consensus.PoSA)
|
||||
//isBor := cfg.chainConfig.Bor != nil
|
||||
|
||||
slowDownLimit := time.NewTicker(time.Second)
|
||||
defer slowDownLimit.Stop()
|
||||
|
||||
@ -480,7 +477,7 @@ Loop:
|
||||
return err
|
||||
}
|
||||
if b == nil {
|
||||
// TODO: panic here and see that overall prodcess deadlock
|
||||
// TODO: panic here and see that overall process deadlock
|
||||
return fmt.Errorf("nil block %d", blockNum)
|
||||
}
|
||||
txs := b.Transactions()
|
||||
@ -580,7 +577,7 @@ Loop:
|
||||
count++
|
||||
applyWorker.RunTxTask(txTask)
|
||||
if err := func() error {
|
||||
if txTask.Final && !isPoSa {
|
||||
if txTask.Final {
|
||||
gasUsed += txTask.UsedGas
|
||||
if gasUsed != txTask.Header.GasUsed {
|
||||
if txTask.BlockNum > 0 { //Disable check for genesis. Maybe need somehow improve it in future - to satisfy TestExecutionSpec
|
||||
|
@ -165,13 +165,10 @@ func executeBlock(
|
||||
var receipts types.Receipts
|
||||
var stateSyncReceipt *types.Receipt
|
||||
var execRs *core.EphemeralExecResult
|
||||
_, isPoSa := cfg.engine.(consensus.PoSA)
|
||||
isBor := cfg.chainConfig.Bor != nil
|
||||
getHashFn := core.GetHashFn(block.Header(), getHeader)
|
||||
|
||||
if isPoSa {
|
||||
execRs, err = core.ExecuteBlockEphemerallyForBSC(cfg.chainConfig, &vmConfig, getHashFn, cfg.engine, block, stateReader, stateWriter, ChainReaderImpl{config: cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, getTracer)
|
||||
} else if isBor {
|
||||
if isBor {
|
||||
execRs, err = core.ExecuteBlockEphemerallyBor(cfg.chainConfig, &vmConfig, getHashFn, cfg.engine, block, stateReader, stateWriter, ChainReaderImpl{config: cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, getTracer)
|
||||
} else {
|
||||
execRs, err = core.ExecuteBlockEphemerally(cfg.chainConfig, &vmConfig, getHashFn, cfg.engine, block, stateReader, stateWriter, ChainReaderImpl{config: cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, getTracer)
|
||||
|
@ -118,15 +118,15 @@ func SpawnStageHeaders(
|
||||
preProgress = s.BlockNumber
|
||||
}
|
||||
|
||||
notBorAndParlia := cfg.chainConfig.Bor == nil && cfg.chainConfig.Parlia == nil
|
||||
notBor := cfg.chainConfig.Bor == nil
|
||||
|
||||
unsettledForkChoice, headHeight := cfg.hd.GetUnsettledForkChoice()
|
||||
if notBorAndParlia && unsettledForkChoice != nil { // some work left to do after unwind
|
||||
if notBor && unsettledForkChoice != nil { // some work left to do after unwind
|
||||
return finishHandlingForkChoice(unsettledForkChoice, headHeight, s, tx, cfg, useExternalTx)
|
||||
}
|
||||
|
||||
transitionedToPoS := cfg.chainConfig.TerminalTotalDifficultyPassed
|
||||
if notBorAndParlia && !transitionedToPoS {
|
||||
if notBor && !transitionedToPoS {
|
||||
var err error
|
||||
transitionedToPoS, err = rawdb.Transitioned(tx, preProgress, cfg.chainConfig.TerminalTotalDifficulty)
|
||||
if err != nil {
|
||||
|
@ -251,7 +251,7 @@ func getNextTransactions(
|
||||
func filterBadTransactions(transactions []types.Transaction, config chain.Config, blockNumber uint64, baseFee *big.Int, simulationTx *memdb.MemoryMutation) ([]types.Transaction, error) {
|
||||
initialCnt := len(transactions)
|
||||
var filtered []types.Transaction
|
||||
gasBailout := config.Consensus == chain.ParliaConsensus
|
||||
gasBailout := false
|
||||
|
||||
missedTxs := 0
|
||||
noSenderCnt := 0
|
||||
|
@ -10,6 +10,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/holiman/uint256"
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
|
||||
"github.com/ledgerwatch/erigon-lib/chain"
|
||||
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
||||
"github.com/ledgerwatch/erigon-lib/common/cmp"
|
||||
@ -22,8 +24,8 @@ import (
|
||||
"github.com/ledgerwatch/erigon-lib/kv/kvcfg"
|
||||
"github.com/ledgerwatch/erigon-lib/kv/rawdbv3"
|
||||
"github.com/ledgerwatch/erigon-lib/state"
|
||||
|
||||
"github.com/ledgerwatch/erigon/consensus"
|
||||
"github.com/ledgerwatch/erigon/consensus/parlia"
|
||||
"github.com/ledgerwatch/erigon/core/rawdb"
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
"github.com/ledgerwatch/erigon/eth/ethconfig/estimate"
|
||||
@ -31,7 +33,6 @@ import (
|
||||
"github.com/ledgerwatch/erigon/turbo/services"
|
||||
"github.com/ledgerwatch/erigon/turbo/snapshotsync"
|
||||
"github.com/ledgerwatch/erigon/turbo/snapshotsync/snapcfg"
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
)
|
||||
|
||||
type SnapshotsCfg struct {
|
||||
@ -214,7 +215,6 @@ func FillDBFromSnapshots(logPrefix string, ctx context.Context, tx kv.RwTx, dirs
|
||||
// for now easier just store them in db
|
||||
td := big.NewInt(0)
|
||||
blockNumBytes := make([]byte, 8)
|
||||
chainReader := &ChainReaderImpl{config: &chainConfig, tx: tx, blockReader: blockReader}
|
||||
if err := snapshotsync.ForEachHeader(ctx, sn, func(header *types.Header) error {
|
||||
blockNum, blockHash := header.Number.Uint64(), header.Hash()
|
||||
td.Add(td, header.Difficulty)
|
||||
@ -230,20 +230,6 @@ func FillDBFromSnapshots(logPrefix string, ctx context.Context, tx kv.RwTx, dirs
|
||||
return err
|
||||
}
|
||||
|
||||
if engine != nil {
|
||||
// consensus may have own database, let's fill it
|
||||
// different consensuses may have some conditions for validators snapshots
|
||||
need := false
|
||||
switch engine.(type) {
|
||||
case *parlia.Parlia:
|
||||
need = (blockNum-1)%(100*parlia.CheckpointInterval) == 0
|
||||
}
|
||||
if need {
|
||||
if err := engine.VerifyHeader(chainReader, header, true /* seal */); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
|
2
go.mod
2
go.mod
@ -3,7 +3,7 @@ module github.com/ledgerwatch/erigon
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/ledgerwatch/erigon-lib v0.0.0-20230413101817-5e9e729d3ce3
|
||||
github.com/ledgerwatch/erigon-lib v0.0.0-20230413113449-ace13f88ddad
|
||||
github.com/ledgerwatch/erigon-snapshot v1.1.1-0.20230404044759-5dec854ce336
|
||||
github.com/ledgerwatch/log/v3 v3.7.0
|
||||
github.com/ledgerwatch/secp256k1 v1.0.0
|
||||
|
4
go.sum
4
go.sum
@ -527,8 +527,8 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3PYPwICLl+/9oulQauOuETfgFvhBDffs0=
|
||||
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
|
||||
github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
|
||||
github.com/ledgerwatch/erigon-lib v0.0.0-20230413101817-5e9e729d3ce3 h1:oo8E+wE18V2awVlVU8w8uuSGPo9zlyzRYRxZGVw5X3w=
|
||||
github.com/ledgerwatch/erigon-lib v0.0.0-20230413101817-5e9e729d3ce3/go.mod h1:jfv6zfkuhalm02Q7wzlmjDdDHf9jxRLO/KM/1aJMhlw=
|
||||
github.com/ledgerwatch/erigon-lib v0.0.0-20230413113449-ace13f88ddad h1:Y9qQM9CVeN9G2GOmBpIGILJenI5ZZ2/7WRRDAkd4hU0=
|
||||
github.com/ledgerwatch/erigon-lib v0.0.0-20230413113449-ace13f88ddad/go.mod h1:jfv6zfkuhalm02Q7wzlmjDdDHf9jxRLO/KM/1aJMhlw=
|
||||
github.com/ledgerwatch/erigon-snapshot v1.1.1-0.20230404044759-5dec854ce336 h1:Yxmt4Wyd0RCLr7UJJAl0ApCP/f5qkWfvHfgPbnI8ghM=
|
||||
github.com/ledgerwatch/erigon-snapshot v1.1.1-0.20230404044759-5dec854ce336/go.mod h1:3AuPxZc85jkehh/HA9h8gabv5MSi3kb/ddtzBsTVJFo=
|
||||
github.com/ledgerwatch/log/v3 v3.7.0 h1:aFPEZdwZx4jzA3+/Pf8wNDN5tCI0cIolq/kfvgcM+og=
|
||||
|
@ -18,15 +18,11 @@ package params
|
||||
|
||||
import "math/big"
|
||||
|
||||
// GasLimitBoundDivisor it can be changed by BSC
|
||||
var (
|
||||
GasLimitBoundDivisor uint64 = 1024 // The bound divisor of the gas limit, used in update calculations.
|
||||
)
|
||||
|
||||
const (
|
||||
MinGasLimit uint64 = 5000 // Minimum the gas limit may ever be.
|
||||
MaxGasLimit uint64 = 0x7fffffffffffffff // Maximum the gas limit may ever be.
|
||||
GenesisGasLimit uint64 = 4712388 // Gas limit of the Genesis block.
|
||||
GasLimitBoundDivisor uint64 = 1024 // The bound divisor of the gas limit, used in update calculations.
|
||||
MinGasLimit uint64 = 5000 // Minimum the gas limit may ever be.
|
||||
MaxGasLimit uint64 = 0x7fffffffffffffff // Maximum the gas limit may ever be.
|
||||
GenesisGasLimit uint64 = 4712388 // Gas limit of the Genesis block.
|
||||
|
||||
MaximumExtraDataSize uint64 = 32 // Maximum size extra data may be after Genesis.
|
||||
CallValueTransferGas uint64 = 9000 // Paid for CALL when the value transfer is non-zero.
|
||||
@ -189,7 +185,3 @@ var (
|
||||
MinimumDifficulty = big.NewInt(131072) // The minimum that the difficulty may ever be.
|
||||
DurationLimit = big.NewInt(13) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not.
|
||||
)
|
||||
|
||||
func ApplyBinanceSmartChainParams() {
|
||||
GasLimitBoundDivisor = 256
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user