diff --git a/README.md b/README.md
index 39654577e..ec5747eba 100644
--- a/README.md
+++ b/README.md
@@ -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`. 🔬 See [Downloader docs](./cmd/downloader/readme.md)
diff --git a/cmd/erigon-el/backend/backend.go b/cmd/erigon-el/backend/backend.go
index 4730b2365..b2011e639 100644
--- a/cmd/erigon-el/backend/backend.go
+++ b/cmd/erigon-el/backend/backend.go
@@ -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
diff --git a/cmd/integration/commands/stages.go b/cmd/integration/commands/stages.go
index a28ac2f8f..81066193e 100644
--- a/cmd/integration/commands/stages.go
+++ b/cmd/integration/commands/stages.go
@@ -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 {
diff --git a/cmd/state/commands/erigon4.go b/cmd/state/commands/erigon4.go
index 2bb5089b3..849fb866f 100644
--- a/cmd/state/commands/erigon4.go
+++ b/cmd/state/commands/erigon4.go
@@ -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 {
diff --git a/cmd/state/commands/root.go b/cmd/state/commands/root.go
index ddbca2889..729a1d9f3 100644
--- a/cmd/state/commands/root.go
+++ b/cmd/state/commands/root.go
@@ -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")
diff --git a/cmd/state/exec3/state.go b/cmd/state/exec3/state.go
index 036e87778..c196eb9ab 100644
--- a/cmd/state/exec3/state.go
+++ b/cmd/state/exec3/state.go
@@ -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()
diff --git a/cmd/state/exec3/state_recon.go b/cmd/state/exec3/state_recon.go
index 3ca57a7a6..750363e28 100644
--- a/cmd/state/exec3/state_recon.go
+++ b/cmd/state/exec3/state_recon.go
@@ -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)
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index 7944a5eca..f6e5e33d9 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -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)
diff --git a/consensus/consensus.go b/consensus/consensus.go
index 829c27517..77939fb6a 100644
--- a/consensus/consensus.go
+++ b/consensus/consensus.go
@@ -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
-}
diff --git a/consensus/parlia/abi.go b/consensus/parlia/abi.go
deleted file mode 100644
index e841eb5cd..000000000
--- a/consensus/parlia/abi.go
+++ /dev/null
@@ -1,1525 +0,0 @@
-package parlia
-
-const validatorSetABI = `
-[
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": false,
- "internalType": "uint256",
- "name": "amount",
- "type": "uint256"
- }
- ],
- "name": "batchTransfer",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "uint256",
- "name": "amount",
- "type": "uint256"
- },
- {
- "indexed": false,
- "internalType": "string",
- "name": "reason",
- "type": "string"
- }
- ],
- "name": "batchTransferFailed",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "uint256",
- "name": "amount",
- "type": "uint256"
- },
- {
- "indexed": false,
- "internalType": "bytes",
- "name": "reason",
- "type": "bytes"
- }
- ],
- "name": "batchTransferLowerFailed",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "validator",
- "type": "address"
- },
- {
- "indexed": false,
- "internalType": "uint256",
- "name": "amount",
- "type": "uint256"
- }
- ],
- "name": "deprecatedDeposit",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address payable",
- "name": "validator",
- "type": "address"
- },
- {
- "indexed": false,
- "internalType": "uint256",
- "name": "amount",
- "type": "uint256"
- }
- ],
- "name": "directTransfer",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address payable",
- "name": "validator",
- "type": "address"
- },
- {
- "indexed": false,
- "internalType": "uint256",
- "name": "amount",
- "type": "uint256"
- }
- ],
- "name": "directTransferFail",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": false,
- "internalType": "string",
- "name": "message",
- "type": "string"
- }
- ],
- "name": "failReasonWithStr",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": false,
- "internalType": "uint256",
- "name": "amount",
- "type": "uint256"
- }
- ],
- "name": "feeBurned",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": false,
- "internalType": "string",
- "name": "key",
- "type": "string"
- },
- {
- "indexed": false,
- "internalType": "bytes",
- "name": "value",
- "type": "bytes"
- }
- ],
- "name": "paramChange",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": false,
- "internalType": "uint256",
- "name": "amount",
- "type": "uint256"
- }
- ],
- "name": "systemTransfer",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": false,
- "internalType": "uint8",
- "name": "channelId",
- "type": "uint8"
- },
- {
- "indexed": false,
- "internalType": "bytes",
- "name": "msgBytes",
- "type": "bytes"
- }
- ],
- "name": "unexpectedPackage",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "validator",
- "type": "address"
- },
- {
- "indexed": false,
- "internalType": "uint256",
- "name": "amount",
- "type": "uint256"
- }
- ],
- "name": "validatorDeposit",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "validator",
- "type": "address"
- }
- ],
- "name": "validatorEmptyJailed",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "validator",
- "type": "address"
- }
- ],
- "name": "validatorEnterMaintenance",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "validator",
- "type": "address"
- }
- ],
- "name": "validatorExitMaintenance",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "validator",
- "type": "address"
- },
- {
- "indexed": false,
- "internalType": "uint256",
- "name": "amount",
- "type": "uint256"
- }
- ],
- "name": "validatorFelony",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "validator",
- "type": "address"
- }
- ],
- "name": "validatorJailed",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "validator",
- "type": "address"
- },
- {
- "indexed": false,
- "internalType": "uint256",
- "name": "amount",
- "type": "uint256"
- }
- ],
- "name": "validatorMisdemeanor",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [],
- "name": "validatorSetUpdated",
- "type": "event"
- },
- {
- "inputs": [],
- "name": "BIND_CHANNELID",
- "outputs": [
- {
- "internalType": "uint8",
- "name": "",
- "type": "uint8"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "BURN_ADDRESS",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "BURN_RATIO_SCALE",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "CODE_OK",
- "outputs": [
- {
- "internalType": "uint32",
- "name": "",
- "type": "uint32"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "CROSS_CHAIN_CONTRACT_ADDR",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "DUSTY_INCOMING",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "EPOCH",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "ERROR_FAIL_CHECK_VALIDATORS",
- "outputs": [
- {
- "internalType": "uint32",
- "name": "",
- "type": "uint32"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "ERROR_FAIL_DECODE",
- "outputs": [
- {
- "internalType": "uint32",
- "name": "",
- "type": "uint32"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "ERROR_LEN_OF_VAL_MISMATCH",
- "outputs": [
- {
- "internalType": "uint32",
- "name": "",
- "type": "uint32"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "ERROR_RELAYFEE_TOO_LARGE",
- "outputs": [
- {
- "internalType": "uint32",
- "name": "",
- "type": "uint32"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "ERROR_UNKNOWN_PACKAGE_TYPE",
- "outputs": [
- {
- "internalType": "uint32",
- "name": "",
- "type": "uint32"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "EXPIRE_TIME_SECOND_GAP",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "GOV_CHANNELID",
- "outputs": [
- {
- "internalType": "uint8",
- "name": "",
- "type": "uint8"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "GOV_HUB_ADDR",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "INCENTIVIZE_ADDR",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "INIT_BURN_RATIO",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "INIT_MAINTAIN_SLASH_SCALE",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "INIT_MAX_NUM_OF_MAINTAINING",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "INIT_NUM_OF_CABINETS",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "INIT_VALIDATORSET_BYTES",
- "outputs": [
- {
- "internalType": "bytes",
- "name": "",
- "type": "bytes"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "JAIL_MESSAGE_TYPE",
- "outputs": [
- {
- "internalType": "uint8",
- "name": "",
- "type": "uint8"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "LIGHT_CLIENT_ADDR",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "MAX_NUM_OF_VALIDATORS",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "PRECISION",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "RELAYERHUB_CONTRACT_ADDR",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "SLASH_CHANNELID",
- "outputs": [
- {
- "internalType": "uint8",
- "name": "",
- "type": "uint8"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "SLASH_CONTRACT_ADDR",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "STAKING_CHANNELID",
- "outputs": [
- {
- "internalType": "uint8",
- "name": "",
- "type": "uint8"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "SYSTEM_ADDRESS",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "SYSTEM_REWARD_ADDR",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "TOKEN_HUB_ADDR",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "TOKEN_MANAGER_ADDR",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "TRANSFER_IN_CHANNELID",
- "outputs": [
- {
- "internalType": "uint8",
- "name": "",
- "type": "uint8"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "TRANSFER_OUT_CHANNELID",
- "outputs": [
- {
- "internalType": "uint8",
- "name": "",
- "type": "uint8"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "VALIDATORS_UPDATE_MESSAGE_TYPE",
- "outputs": [
- {
- "internalType": "uint8",
- "name": "",
- "type": "uint8"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "VALIDATOR_CONTRACT_ADDR",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "alreadyInit",
- "outputs": [
- {
- "internalType": "bool",
- "name": "",
- "type": "bool"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "bscChainID",
- "outputs": [
- {
- "internalType": "uint16",
- "name": "",
- "type": "uint16"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "burnRatio",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "burnRatioInitialized",
- "outputs": [
- {
- "internalType": "bool",
- "name": "",
- "type": "bool"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "name": "currentValidatorSet",
- "outputs": [
- {
- "internalType": "address",
- "name": "consensusAddress",
- "type": "address"
- },
- {
- "internalType": "address payable",
- "name": "feeAddress",
- "type": "address"
- },
- {
- "internalType": "address",
- "name": "BBCFeeAddress",
- "type": "address"
- },
- {
- "internalType": "uint64",
- "name": "votingPower",
- "type": "uint64"
- },
- {
- "internalType": "bool",
- "name": "jailed",
- "type": "bool"
- },
- {
- "internalType": "uint256",
- "name": "incoming",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "name": "currentValidatorSetMap",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "expireTimeSecondGap",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "maintainSlashScale",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "maxNumOfCandidates",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "maxNumOfMaintaining",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "maxNumOfWorkingCandidates",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "numOfCabinets",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "numOfJailed",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "numOfMaintaining",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "totalInComing",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "valAddr",
- "type": "address"
- },
- {
- "internalType": "address",
- "name": "slashAddr",
- "type": "address"
- },
- {
- "internalType": "address",
- "name": "rewardAddr",
- "type": "address"
- },
- {
- "internalType": "address",
- "name": "lightAddr",
- "type": "address"
- },
- {
- "internalType": "address",
- "name": "tokenHubAddr",
- "type": "address"
- },
- {
- "internalType": "address",
- "name": "incentivizeAddr",
- "type": "address"
- },
- {
- "internalType": "address",
- "name": "relayerHubAddr",
- "type": "address"
- },
- {
- "internalType": "address",
- "name": "govHub",
- "type": "address"
- },
- {
- "internalType": "address",
- "name": "tokenManagerAddr",
- "type": "address"
- },
- {
- "internalType": "address",
- "name": "crossChain",
- "type": "address"
- }
- ],
- "name": "updateContractAddr",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "name": "validatorExtraSet",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "enterMaintenanceHeight",
- "type": "uint256"
- },
- {
- "internalType": "bool",
- "name": "isMaintaining",
- "type": "bool"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "init",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "uint8",
- "name": "",
- "type": "uint8"
- },
- {
- "internalType": "bytes",
- "name": "msgBytes",
- "type": "bytes"
- }
- ],
- "name": "handleSynPackage",
- "outputs": [
- {
- "internalType": "bytes",
- "name": "responsePayload",
- "type": "bytes"
- }
- ],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "uint8",
- "name": "channelId",
- "type": "uint8"
- },
- {
- "internalType": "bytes",
- "name": "msgBytes",
- "type": "bytes"
- }
- ],
- "name": "handleAckPackage",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "uint8",
- "name": "channelId",
- "type": "uint8"
- },
- {
- "internalType": "bytes",
- "name": "msgBytes",
- "type": "bytes"
- }
- ],
- "name": "handleFailAckPackage",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "valAddr",
- "type": "address"
- }
- ],
- "name": "deposit",
- "outputs": [],
- "stateMutability": "payable",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "getMiningValidators",
- "outputs": [
- {
- "internalType": "address[]",
- "name": "",
- "type": "address[]"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "getValidators",
- "outputs": [
- {
- "internalType": "address[]",
- "name": "",
- "type": "address[]"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "uint256",
- "name": "index",
- "type": "uint256"
- }
- ],
- "name": "isWorkingValidator",
- "outputs": [
- {
- "internalType": "bool",
- "name": "",
- "type": "bool"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "validator",
- "type": "address"
- }
- ],
- "name": "getIncoming",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "validator",
- "type": "address"
- }
- ],
- "name": "isCurrentValidator",
- "outputs": [
- {
- "internalType": "bool",
- "name": "",
- "type": "bool"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "validator",
- "type": "address"
- }
- ],
- "name": "misdemeanor",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "validator",
- "type": "address"
- }
- ],
- "name": "felony",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "_validator",
- "type": "address"
- }
- ],
- "name": "getCurrentValidatorIndex",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "uint256",
- "name": "index",
- "type": "uint256"
- }
- ],
- "name": "canEnterMaintenance",
- "outputs": [
- {
- "internalType": "bool",
- "name": "",
- "type": "bool"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "enterMaintenance",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "exitMaintenance",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "string",
- "name": "key",
- "type": "string"
- },
- {
- "internalType": "bytes",
- "name": "value",
- "type": "bytes"
- }
- ],
- "name": "updateParam",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "validator",
- "type": "address"
- }
- ],
- "name": "isValidatorExist",
- "outputs": [
- {
- "internalType": "bool",
- "name": "",
- "type": "bool"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "getMaintainingValidators",
- "outputs": [
- {
- "internalType": "address[]",
- "name": "maintainingValidators",
- "type": "address[]"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- }
- ]
-`
-
-const slashABI = `
-[
- {
- "anonymous": false,
- "inputs": [],
- "name": "indicatorCleaned",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "validator",
- "type": "address"
- }
- ],
- "name": "validatorSlashed",
- "type": "event"
- },
- {
- "inputs": [],
- "name": "FELONY_THRESHOLD",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "MISDEMEANOR_THRESHOLD",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "SYSTEM_ADDRESS",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "VALIDATOR_CONTRACT_ADDR",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "previousHeight",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "validator",
- "type": "address"
- }
- ],
- "name": "slash",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "clean",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "validator",
- "type": "address"
- }
- ],
- "name": "getSlashIndicator",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- },
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- }
- ]
-`
diff --git a/consensus/parlia/api.go b/consensus/parlia/api.go
deleted file mode 100644
index 066414abd..000000000
--- a/consensus/parlia/api.go
+++ /dev/null
@@ -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 .
-
-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
-}
diff --git a/consensus/parlia/parlia.go b/consensus/parlia/parlia.go
deleted file mode 100644
index 67c97f7a5..000000000
--- a/consensus/parlia/parlia.go
+++ /dev/null
@@ -1,1278 +0,0 @@
-package parlia
-
-import (
- "bytes"
- "context"
- "encoding/hex"
- "errors"
- "fmt"
- "io"
- "math/big"
- "sort"
- "strings"
- "sync"
- "time"
-
- lru "github.com/hashicorp/golang-lru/v2"
- "github.com/holiman/uint256"
- "github.com/ledgerwatch/log/v3"
- "golang.org/x/exp/slices"
-
- "github.com/ledgerwatch/erigon-lib/chain"
- libcommon "github.com/ledgerwatch/erigon-lib/common"
- "github.com/ledgerwatch/erigon-lib/common/hexutility"
- "github.com/ledgerwatch/erigon-lib/common/length"
- "github.com/ledgerwatch/erigon-lib/kv"
-
- "github.com/ledgerwatch/erigon/accounts/abi"
- "github.com/ledgerwatch/erigon/common/math"
- "github.com/ledgerwatch/erigon/common/u256"
- "github.com/ledgerwatch/erigon/consensus"
- "github.com/ledgerwatch/erigon/consensus/misc"
- "github.com/ledgerwatch/erigon/core"
- "github.com/ledgerwatch/erigon/core/forkid"
- "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/crypto"
- "github.com/ledgerwatch/erigon/crypto/cryptopool"
- "github.com/ledgerwatch/erigon/params"
- "github.com/ledgerwatch/erigon/rlp"
- "github.com/ledgerwatch/erigon/rpc"
- "github.com/ledgerwatch/erigon/turbo/snapshotsync"
-)
-
-const (
- inMemorySnapshots = 128 // Number of recent snapshots to keep in memory
- inMemorySignatures = 4096 // Number of recent block signatures to keep in memory
-
- CheckpointInterval = 1024 // Number of blocks after which to save the snapshot to the database
- defaultEpochLength = uint64(100) // Default number of blocks of checkpoint to update validatorSet from contract
-
- extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity
- extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal
- nextForkHashSize = 4 // Fixed number of extra-data suffix bytes reserved for nextForkHash.
-
- validatorBytesLength = length.Addr
- wiggleTime = uint64(1) // second, Random delay (per signer) to allow concurrent signers
- initialBackOffTime = uint64(1) // second
- processBackOffTime = uint64(1) // second
-
- systemRewardPercent = 4 // it means 1/2^4 = 1/16 percentage of gas fee incoming will be distributed to system
-)
-
-var (
- uncleHash = types.CalcUncleHash(nil) // Always Keccak256(RLP([])) as uncles are meaningless outside of PoW.
- diffInTurn = big.NewInt(2) // Block difficulty for in-turn signatures
- diffNoTurn = big.NewInt(1) // Block difficulty for out-of-turn signatures
- // 100 native token
- maxSystemBalance = new(uint256.Int).Mul(uint256.NewInt(100), uint256.NewInt(params.Ether))
-
- systemContracts = map[libcommon.Address]struct{}{
- systemcontracts.ValidatorContract: {},
- systemcontracts.SlashContract: {},
- systemcontracts.SystemRewardContract: {},
- systemcontracts.LightClientContract: {},
- systemcontracts.RelayerHubContract: {},
- systemcontracts.GovHubContract: {},
- systemcontracts.TokenHubContract: {},
- systemcontracts.RelayerIncentivizeContract: {},
- systemcontracts.CrossChainContract: {},
- }
-)
-
-// Various error messages to mark blocks invalid. These should be private to
-// prevent engine specific errors from being referenced in the remainder of the
-// codebase, inherently breaking if the engine is swapped out. Please put common
-// error types into the consensus package.
-var (
- // errUnknownBlock is returned when the list of validators is requested for a block
- // that is not part of the local blockchain.
- errUnknownBlock = errors.New("unknown block")
-
- // errMissingVanity is returned if a block's extra-data section is shorter than
- // 32 bytes, which is required to store the signer vanity.
- errMissingVanity = errors.New("extra-data 32 byte vanity prefix missing")
-
- // errMissingSignature is returned if a block's extra-data section doesn't seem
- // to contain a 65 byte secp256k1 signature.
- errMissingSignature = errors.New("extra-data 65 byte signature suffix missing")
-
- // errExtraValidators is returned if non-sprint-end block contain validator data in
- // their extra-data fields.
- errExtraValidators = errors.New("non-sprint-end block contains extra validator list")
-
- // errInvalidSpanValidators is returned if a block contains an
- // invalid list of validators (i.e. non divisible by 20 bytes).
- errInvalidSpanValidators = errors.New("invalid validator list on sprint end block")
-
- // errInvalidMixDigest is returned if a block's mix digest is non-zero.
- errInvalidMixDigest = errors.New("non-zero mix digest")
-
- // errInvalidUncleHash is returned if a block contains an non-empty uncle list.
- errInvalidUncleHash = errors.New("non empty uncle hash")
-
- // errMismatchingEpochValidators is returned if a sprint block contains a
- // list of validators different than the one the local node calculated.
- errMismatchingEpochValidators = errors.New("mismatching validator list on epoch block")
-
- // errInvalidDifficulty is returned if the difficulty of a block is missing.
- errInvalidDifficulty = errors.New("invalid difficulty")
-
- // errWrongDifficulty is returned if the difficulty of a block doesn't match the
- // turn of the signer.
- errWrongDifficulty = errors.New("wrong difficulty")
-
- // errOutOfRangeChain is returned if an authorization list is attempted to
- // be modified via out-of-range or non-contiguous headers.
- errOutOfRangeChain = errors.New("out of range or non-contiguous chain")
-
- // errBlockHashInconsistent is returned if an authorization list is attempted to
- // insert an inconsistent block.
- errBlockHashInconsistent = errors.New("the block hash is inconsistent")
-
- // errUnauthorizedValidator is returned if a header is signed by a non-authorized entity.
- errUnauthorizedValidator = errors.New("unauthorized validator")
-
- // errCoinBaseMisMatch is returned if a header's coinbase do not match with signature
- errCoinBaseMisMatch = errors.New("coinbase do not match with signature")
-
- // errRecentlySigned is returned if a header is signed by an authorized entity
- // that already signed a header recently, thus is temporarily not allowed to.
- errRecentlySigned = errors.New("recently signed")
-)
-
-// SignFn is a signer callback function to request a header to be signed by a
-// backing account.
-type SignFn func(validator libcommon.Address, payload []byte, chainId *big.Int) ([]byte, error)
-
-// ecrecover extracts the Ethereum account address from a signed header.
-func ecrecover(header *types.Header, sigCache *lru.ARCCache[libcommon.Hash, libcommon.Address], chainId *big.Int) (libcommon.Address, error) {
- // If the signature's already cached, return that
- hash := header.Hash()
- if address, known := sigCache.Get(hash); known {
- return address, nil
- }
- // Retrieve the signature from the header extra-data
- if len(header.Extra) < extraSeal {
- return libcommon.Address{}, errMissingSignature
- }
- signature := header.Extra[len(header.Extra)-extraSeal:]
-
- // Recover the public key and the Ethereum address
- pubkey, err := crypto.Ecrecover(SealHash(header, chainId).Bytes(), signature)
- if err != nil {
- return libcommon.Address{}, err
- }
- var signer libcommon.Address
- copy(signer[:], crypto.Keccak256(pubkey[1:])[12:])
-
- sigCache.Add(hash, signer)
- return signer, nil
-}
-
-// SealHash returns the hash of a block prior to it being sealed.
-func SealHash(header *types.Header, chainId *big.Int) (hash libcommon.Hash) {
- hasher := cryptopool.NewLegacyKeccak256()
- defer cryptopool.ReturnToPoolKeccak256(hasher)
-
- encodeSigHeader(hasher, header, chainId)
- hasher.Sum(hash[:0])
- return hash
-}
-
-func encodeSigHeader(w io.Writer, header *types.Header, chainId *big.Int) {
- err := rlp.Encode(w, []interface{}{
- chainId,
- header.ParentHash,
- header.UncleHash,
- header.Coinbase,
- header.Root,
- header.TxHash,
- header.ReceiptHash,
- header.Bloom,
- header.Difficulty,
- header.Number,
- header.GasLimit,
- header.GasUsed,
- header.Time,
- header.Extra[:len(header.Extra)-65], // this will panic if extra is too short, should check before calling encodeSigHeader
- header.MixDigest,
- header.Nonce,
- })
- if err != nil {
- panic("can't encode: " + err.Error())
- }
-}
-
-// parliaRLP returns the rlp bytes which needs to be signed for the parlia
-// sealing. The RLP to sign consists of the entire header apart from the 65 byte signature
-// contained at the end of the extra data.
-//
-// Note, the method requires the extra data to be at least 65 bytes, otherwise it
-// panics. This is done to avoid accidentally using both forms (signature present
-// or not), which could be abused to produce different hashes for the same header.
-func parliaRLP(header *types.Header, chainId *big.Int) []byte {
- b := new(bytes.Buffer)
- encodeSigHeader(b, header, chainId)
- return b.Bytes()
-}
-
-type Parlia struct {
- chainConfig *chain.Config // Chain config
- config *chain.ParliaConfig // Consensus engine configuration parameters for parlia consensus
- genesisHash libcommon.Hash
- db kv.RwDB // Database to store and retrieve snapshot checkpoints
- chainDb kv.RwDB
-
- recentSnaps *lru.ARCCache[libcommon.Hash, *Snapshot] // Snapshots for recent block to speed up
- signatures *lru.ARCCache[libcommon.Hash, libcommon.Address] // Signatures of recent blocks to speed up mining
-
- signer *types.Signer
-
- val libcommon.Address // Ethereum address of the signing key
- signFn SignFn // Signer function to authorize hashes with
-
- signerLock sync.RWMutex // Protects the signer fields
-
- snapLock sync.RWMutex // Protects snapshots creation
-
- validatorSetABI abi.ABI
- slashABI abi.ABI
-
- // The fields below are for testing only
- fakeDiff bool // Skip difficulty verifications
- heightForks, timeForks []uint64 // Forks extracted from the chainConfig
- snapshots *snapshotsync.RoSnapshots
-}
-
-// New creates a Parlia consensus engine.
-func New(
- chainConfig *chain.Config,
- db kv.RwDB,
- snapshots *snapshotsync.RoSnapshots,
- chainDb kv.RwDB,
-) *Parlia {
- // get parlia config
- parliaConfig := chainConfig.Parlia
-
- // Set any missing consensus parameters to their defaults
- if parliaConfig != nil && parliaConfig.Epoch == 0 {
- parliaConfig.Epoch = defaultEpochLength
- }
-
- // Allocate the snapshot caches and create the engine
- recentSnaps, err := lru.NewARC[libcommon.Hash, *Snapshot](inMemorySnapshots)
- if err != nil {
- panic(err)
- }
- signatures, err := lru.NewARC[libcommon.Hash, libcommon.Address](inMemorySignatures)
- if err != nil {
- panic(err)
- }
- vABI, err := abi.JSON(strings.NewReader(validatorSetABI))
- if err != nil {
- panic(err)
- }
- sABI, err := abi.JSON(strings.NewReader(slashABI))
- if err != nil {
- panic(err)
- }
- c := &Parlia{
- chainConfig: chainConfig,
- config: parliaConfig,
- db: db,
- chainDb: chainDb,
- recentSnaps: recentSnaps,
- signatures: signatures,
- validatorSetABI: vABI,
- slashABI: sABI,
- signer: types.LatestSigner(chainConfig),
- snapshots: snapshots,
- }
- c.heightForks, c.timeForks = forkid.GatherForks(chainConfig)
-
- return c
-}
-
-// Type returns underlying consensus engine
-func (p *Parlia) Type() chain.ConsensusName {
- return chain.ParliaConsensus
-}
-
-// Author retrieves the Ethereum address of the account that minted the given
-// block, which may be different from the header's coinbase if a consensus
-// engine is based on signatures.
-// This is thread-safe (only access the header.Coinbase)
-func (p *Parlia) Author(header *types.Header) (libcommon.Address, error) {
- return header.Coinbase, nil
-}
-
-// VerifyHeader checks whether a header conforms to the consensus rules of a
-// given engine. Verifying the seal may be done optionally here, or explicitly
-// via the VerifySeal method.
-func (p *Parlia) VerifyHeader(chain consensus.ChainHeaderReader, header *types.Header, seal bool) error {
- return p.verifyHeader(chain, header, nil)
-}
-
-// VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers
-// concurrently. The method returns a quit channel to abort the operations and
-// a results channel to retrieve the async verifications (the order is that of
-// the input slice).
-func (p *Parlia) VerifyHeaders(chain consensus.ChainHeaderReader, headers []*types.Header, seals []bool) error {
- for i, header := range headers {
- err := p.verifyHeader(chain, header, headers[:i])
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-// verifyHeader checks whether a header conforms to the consensus rules.The
-// caller may optionally pass in a batch of parents (ascending order) to avoid
-// looking those up from the database. This is useful for concurrently verifying
-// a batch of new headers.
-func (p *Parlia) verifyHeader(chain consensus.ChainHeaderReader, header *types.Header, parents []*types.Header) error {
- if header.Number == nil {
- return errUnknownBlock
- }
- number := header.Number.Uint64()
-
- // Don't waste time checking blocks from the future
- if header.Time > uint64(time.Now().Unix()) {
- return fmt.Errorf("header %d, time %d, now %d, %w", header.Number.Uint64(), header.Time, time.Now().Unix(), consensus.ErrFutureBlock)
- }
- // Check that the extra-data contains the vanity, validators and signature.
- if len(header.Extra) < extraVanity {
- return errMissingVanity
- }
- if len(header.Extra) < extraVanity+extraSeal {
- return errMissingSignature
- }
- // check extra data
- isEpoch := number%p.config.Epoch == 0
-
- // Ensure that the extra-data contains a signer list on checkpoint, but none otherwise
- signersBytes := len(header.Extra) - extraVanity - extraSeal
- if !isEpoch && signersBytes != 0 {
- return errExtraValidators
- }
-
- if isEpoch && signersBytes%validatorBytesLength != 0 {
- return errInvalidSpanValidators
- }
-
- // Ensure that the mix digest is zero as we don't have fork protection currently
- if header.MixDigest != (libcommon.Hash{}) {
- return errInvalidMixDigest
- }
- // Ensure that the block doesn't contain any uncles which are meaningless in PoA
- if header.UncleHash != uncleHash {
- return errInvalidUncleHash
- }
- // Ensure that the block's difficulty is meaningful (may not be correct at this point)
- if number > 0 {
- if header.Difficulty == nil {
- return errInvalidDifficulty
- }
- }
-
- if header.WithdrawalsHash != nil {
- return consensus.ErrUnexpectedWithdrawals
- }
-
- // All basic checks passed, verify cascading fields
- return p.verifyCascadingFields(chain, header, parents)
-}
-
-// verifyCascadingFields verifies all the header fields that are not standalone,
-// rather depend on a batch of previous headers. The caller may optionally pass
-// in a batch of parents (ascending order) to avoid looking those up from the
-// database. This is useful for concurrently verifying a batch of new headers.
-func (p *Parlia) verifyCascadingFields(chain consensus.ChainHeaderReader, header *types.Header, parents []*types.Header) error {
- // The genesis block is the always valid dead-end
- number := header.Number.Uint64()
- if number == 0 {
- return nil
- }
-
- var parent *types.Header
- if len(parents) > 0 {
- parent = parents[len(parents)-1]
- } else {
- parent = chain.GetHeader(header.ParentHash, number-1)
- }
-
- if parent == nil || parent.Number.Uint64() != number-1 || parent.Hash() != header.ParentHash {
- return consensus.ErrUnknownAncestor
- }
-
- snap, err := p.snapshot(chain, number-1, header.ParentHash, parents, true /* verify */)
- if err != nil {
- return err
- }
-
- err = p.blockTimeVerifyForRamanujanFork(snap, header, parent)
- if err != nil {
- return err
- }
-
- // Verify that the gas limit is <= 2^63-1
- capacity := uint64(0x7fffffffffffffff)
- if header.GasLimit > capacity {
- return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, capacity)
- }
- // Verify that the gasUsed is <= gasLimit
- if header.GasUsed > header.GasLimit {
- return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit)
- }
-
- // Verify that the gas limit remains within allowed bounds
- diff := int64(parent.GasLimit) - int64(header.GasLimit)
- if diff < 0 {
- diff *= -1
- }
- limit := parent.GasLimit / params.GasLimitBoundDivisor
-
- if uint64(diff) >= limit || header.GasLimit < params.MinGasLimit {
- return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit)
- }
-
- // All basic checks passed, verify the seal and return
- return p.verifySeal(chain, header, parents)
-}
-
-// verifySeal checks whether the signature contained in the header satisfies the
-// consensus protocol requirements. The method accepts an optional list of parent
-// headers that aren't yet part of the local blockchain to generate the snapshots
-// from.
-func (p *Parlia) verifySeal(chain consensus.ChainHeaderReader, header *types.Header, parents []*types.Header) error {
- // Verifying the genesis block is not supported
- number := header.Number.Uint64()
- if number == 0 {
- return errUnknownBlock
- }
- // Retrieve the snapshot needed to verify this header and cache it
- snap, err := p.snapshot(chain, number-1, header.ParentHash, parents, true /* verify */)
- if err != nil {
- return err
- }
-
- // Resolve the authorization key and check against validators
- signer, err := ecrecover(header, p.signatures, p.chainConfig.ChainID)
- if err != nil {
- return err
- }
-
- if signer != header.Coinbase {
- return errCoinBaseMisMatch
- }
-
- if _, ok := snap.Validators[signer]; !ok {
- return fmt.Errorf("parlia.verifySeal: headerNum=%d, validator=%x, %w", header.Number.Uint64(), signer.Bytes(), errUnauthorizedValidator)
- }
-
- for seen, recent := range snap.Recents {
- if recent == signer {
- // Signer is among recents, only fail if the current block doesn't shift it out
- if limit := uint64(len(snap.Validators)/2 + 1); seen > number-limit {
- return errRecentlySigned
- }
- }
- }
-
- // Ensure that the difficulty corresponds to the turn-ness of the signer
- if !p.fakeDiff {
- inturn := snap.inturn(signer)
- if inturn && header.Difficulty.Cmp(diffInTurn) != 0 {
- return errWrongDifficulty
- }
- if !inturn && header.Difficulty.Cmp(diffNoTurn) != 0 {
- return errWrongDifficulty
- }
- }
-
- return nil
-}
-
-// snapshot retrieves the authorization snapshot at a given point in time.
-func (p *Parlia) snapshot(chain consensus.ChainHeaderReader, number uint64, hash libcommon.Hash, parents []*types.Header, verify bool) (*Snapshot, error) {
- // Search for a snapshot in memory or on disk for checkpoints
- var (
- headers []*types.Header
- snap *Snapshot
- doLog bool
- )
-
- if s, ok := p.recentSnaps.Get(hash); ok {
- snap = s
- } else {
- p.snapLock.Lock()
- defer p.snapLock.Unlock()
- doLog = true
- }
-
- for snap == nil {
- // If an in-memory snapshot was found, use that
- if s, ok := p.recentSnaps.Get(hash); ok {
- snap = s
- break
- }
-
- // If an on-disk checkpoint snapshot can be found, use that
- if number%CheckpointInterval == 0 {
- if s, err := loadSnapshot(p.config, p.signatures, p.db, number, hash); err == nil {
- //log.Trace("Loaded snapshot from disk", "number", number, "hash", hash)
- snap = s
- if !verify || snap != nil {
- break
- }
- }
- }
- if number == 0 {
- // Headers included into the snapshots have to be trusted as checkpoints
- checkpoint := chain.GetHeader(hash, number)
- if checkpoint != nil {
- validatorBytes := checkpoint.Extra[extraVanity : len(checkpoint.Extra)-extraSeal]
- // get validators from headers
- validators, err := ParseValidators(validatorBytes)
- if err != nil {
- return nil, err
- }
- // new snapshot
- snap = newSnapshot(p.config, p.signatures, number, hash, validators)
- if err := snap.store(p.db); err != nil {
- return nil, err
- }
- break
- }
- }
-
- // No snapshot for this header, gather the header and move backward
- var header *types.Header
- if len(parents) > 0 {
- // If we have explicit parents, pick from there (enforced)
- header = parents[len(parents)-1]
- if header.Hash() != hash || header.Number.Uint64() != number {
- return nil, consensus.ErrUnknownAncestor
- }
- parents = parents[:len(parents)-1]
- } else {
- if doLog && number%100_000 == 0 {
- // No explicit parents (or no more left), reach out to the database
- log.Info("[parlia] snapshots build, gather headers", "block", number)
- }
- header = chain.GetHeader(hash, number)
- if header == nil {
- return nil, consensus.ErrUnknownAncestor
- }
- }
- headers = append(headers, header)
- number, hash = number-1, header.ParentHash
- }
-
- // check if snapshot is nil
- if snap == nil {
- return nil, fmt.Errorf("unknown error while retrieving snapshot at block number %v", number)
- }
-
- // Previous snapshot found, apply any pending headers on top of it
- for i := 0; i < len(headers)/2; i++ {
- headers[i], headers[len(headers)-1-i] = headers[len(headers)-1-i], headers[i]
- }
- snap, err := snap.apply(headers, chain, parents, p.chainConfig.ChainID, doLog)
- if err != nil {
- return nil, err
- }
- p.recentSnaps.Add(snap.Hash, snap)
-
- // If we've generated a new checkpoint snapshot, save to disk
- if verify && snap.Number%CheckpointInterval == 0 && len(headers) > 0 {
- if err = snap.store(p.db); err != nil {
- return nil, err
- }
- //log.Trace("Stored snapshot to disk", "number", snap.Number, "hash", snap.Hash)
- }
- return snap, err
-}
-
-// VerifyUncles verifies that the given block's uncles conform to the consensus
-// rules of a given engine.
-func (p *Parlia) VerifyUncles(chain consensus.ChainReader, header *types.Header, uncles []*types.Header) error {
- if len(uncles) > 0 {
- return errors.New("uncles not allowed")
- }
- return nil
-}
-
-// Prepare initializes the consensus fields of a block header according to the
-// rules of a particular engine. The changes are executed inline.
-func (p *Parlia) Prepare(chain consensus.ChainHeaderReader, header *types.Header, ibs *state.IntraBlockState) error {
- header.Coinbase = p.val
- header.Nonce = types.BlockNonce{}
-
- number := header.Number.Uint64()
- snap, err := p.snapshot(chain, number-1, header.ParentHash, nil, false /* verify */)
- if err != nil {
- return err
- }
-
- parent := chain.GetHeader(header.ParentHash, number-1)
- if parent == nil {
- return consensus.ErrUnknownAncestor
- }
-
- // Set the correct difficulty
- header.Difficulty = CalcDifficulty(snap, p.val)
-
- // Ensure the timestamp has the correct delay
- header.Time = p.blockTimeForRamanujanFork(snap, header, parent)
- if header.Time < uint64(time.Now().Unix()) {
- header.Time = uint64(time.Now().Unix())
- }
-
- // Ensure the extra data has all it's components
- if len(header.Extra) < extraVanity-nextForkHashSize {
- header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, extraVanity-nextForkHashSize-len(header.Extra))...)
- }
- header.Extra = header.Extra[:extraVanity-nextForkHashSize]
- nextForkHash := forkid.NextForkHashFromForks(p.heightForks, p.timeForks, p.genesisHash, number, header.Time)
- header.Extra = append(header.Extra, nextForkHash[:]...)
-
- if number%p.config.Epoch == 0 {
- newValidators, err := p.getCurrentValidators(parent, ibs)
- if err != nil {
- return err
- }
- // sort validator by address
- sort.Sort(validatorsAscending(newValidators))
- for _, validator := range newValidators {
- header.Extra = append(header.Extra, validator.Bytes()...)
- }
- }
-
- // add extra seal space
- header.Extra = append(header.Extra, make([]byte, extraSeal)...)
-
- // Mix digest is reserved for now, set to empty
- header.MixDigest = libcommon.Hash{}
-
- return nil
-}
-
-// Initialize runs any pre-transaction state modifications (e.g. epoch start)
-func (p *Parlia) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, header *types.Header,
- state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall) {
-}
-
-func (p *Parlia) splitTxs(txs types.Transactions, header *types.Header) (userTxs types.Transactions, systemTxs types.Transactions, err error) {
- userTxs = types.Transactions{}
- systemTxs = types.Transactions{}
- for _, tx := range txs {
- isSystemTx, err2 := p.IsSystemTransaction(tx, header)
- if err2 != nil {
- err = err2
- return
- }
- if isSystemTx {
- systemTxs = append(systemTxs, tx)
- } else {
- userTxs = append(userTxs, tx)
- }
- }
- return
-}
-
-// Finalize runs any post-transaction state modifications (e.g. block rewards)
-// but does not assemble the block.
-//
-// Note: The block header and state database might be updated to reflect any
-// consensus rules that happen at finalization (e.g. block rewards).
-func (p *Parlia) Finalize(_ *chain.Config, header *types.Header, state *state.IntraBlockState,
- txs types.Transactions, _ []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal,
- chain consensus.ChainHeaderReader, syscall consensus.SystemCall,
-) (types.Transactions, types.Receipts, error) {
- return p.finalize(header, state, txs, receipts, chain, false)
-}
-
-func (p *Parlia) finalize(header *types.Header, state *state.IntraBlockState, txs types.Transactions,
- receipts types.Receipts, chain consensus.ChainHeaderReader, mining bool,
-) (types.Transactions, types.Receipts, error) {
- userTxs, systemTxs, err := p.splitTxs(txs, header)
- if err != nil {
- return nil, nil, err
- }
- txs = userTxs
- // warn if not in majority fork
- number := header.Number.Uint64()
- snap, err := p.snapshot(chain, number-1, header.ParentHash, nil, false /* verify */)
- if err != nil {
- return nil, nil, err
- }
- /*
- nextForkHash := forkid.NextForkHashFromForks(p.forks, p.genesisHash, number)
- nextForkHashStr := hex.EncodeToString(nextForkHash[:])
- if !snap.isMajorityFork(nextForkHashStr) {
- log.Debug("[parlia] there is a possible fork, and your client is not the majority. Please check...", "nextForkHash", nextForkHashStr)
- }
- */
- // If the block is an epoch end block, verify the validator list
- // The verification can only be done when the state is ready, it can't be done in VerifyHeader.
- if number%p.config.Epoch == 0 {
- parentHeader := chain.GetHeader(header.ParentHash, number-1)
- newValidators, err := p.getCurrentValidators(parentHeader, state)
- if err != nil {
- return nil, nil, err
- }
- // sort validator by address
- sort.Sort(validatorsAscending(newValidators))
- validatorsBytes := make([]byte, len(newValidators)*validatorBytesLength)
- for i, validator := range newValidators {
- copy(validatorsBytes[i*validatorBytesLength:], validator.Bytes())
- }
-
- extraSuffix := len(header.Extra) - extraSeal
- if !bytes.Equal(header.Extra[extraVanity:extraSuffix], validatorsBytes) {
- return nil, nil, errMismatchingEpochValidators
- }
- }
- // No block rewards in PoA, so the state remains as is and uncles are dropped
- if number == 1 {
- var err error
- if txs, systemTxs, receipts, err = p.initContract(state, header, txs, receipts, systemTxs, &header.GasUsed, mining); err != nil {
- log.Error("[parlia] init contract failed", "err", err)
- return nil, nil, fmt.Errorf("init contract failed: %v", err)
- }
- }
- if header.Difficulty.Cmp(diffInTurn) != 0 {
- spoiledVal := snap.supposeValidator()
- signedRecently := false
- for _, recent := range snap.Recents {
- if recent == spoiledVal {
- signedRecently = true
- break
- }
- }
- if !signedRecently {
- //log.Trace("slash validator", "block hash", header.Hash(), "address", spoiledVal)
- var tx types.Transaction
- var receipt *types.Receipt
- if systemTxs, tx, receipt, err = p.slash(spoiledVal, state, header, len(txs), systemTxs, &header.GasUsed, mining); err != nil {
- // it is possible that slash validator failed because of the slash channel is disabled.
- log.Error("slash validator failed", "block hash", header.Hash(), "address", spoiledVal, "error", err)
- } else {
- txs = append(txs, tx)
- receipts = append(receipts, receipt)
- log.Debug("slash successful", "txns", txs.Len(), "receipts", len(receipts), "gasUsed", header.GasUsed)
- }
- }
- }
- if txs, systemTxs, receipts, err = p.distributeIncoming(header.Coinbase, state, header, txs, receipts, systemTxs, &header.GasUsed, mining); err != nil {
- //log.Error("distributeIncoming", "block hash", header.Hash(), "error", err, "systemTxs", len(systemTxs))
- return nil, nil, err
- }
- //log.Debug("distribute successful", "txns", txs.Len(), "receipts", len(receipts), "gasUsed", header.GasUsed)
- if len(systemTxs) > 0 {
- return nil, nil, fmt.Errorf("the length of systemTxs is still %d", len(systemTxs))
- }
- // Re-order receipts so that are in right order
- slices.SortFunc(receipts, func(a, b *types.Receipt) bool { return a.TransactionIndex < b.TransactionIndex })
- return txs, receipts, nil
-}
-
-// FinalizeAndAssemble runs any post-transaction state modifications (e.g. block
-// rewards) and assembles the final block.
-//
-// Note: The block header and state database might be updated to reflect any
-// consensus rules that happen at finalization (e.g. block rewards).
-func (p *Parlia) FinalizeAndAssemble(_ *chain.Config, header *types.Header, state *state.IntraBlockState,
- txs types.Transactions, _ []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal,
- chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call,
-) (*types.Block, types.Transactions, types.Receipts, error) {
- outTxs, outReceipts, err := p.finalize(header, state, txs, receipts, chain, true)
- if err != nil {
- return nil, nil, nil, err
- }
- return types.NewBlock(header, outTxs, nil, outReceipts, withdrawals), outTxs, outReceipts, nil
-}
-
-// Authorize injects a private key into the consensus engine to mint new blocks
-// with.
-func (p *Parlia) Authorize(val libcommon.Address, signFn SignFn) {
- p.signerLock.Lock()
- defer p.signerLock.Unlock()
-
- p.val = val
- p.signFn = signFn
-}
-
-// Seal generates a new sealing request for the given input block and pushes
-// the result into the given channel.
-//
-// Note, the method returns immediately and will send the result async. More
-// than one result may also be returned depending on the consensus algorithm.
-func (p *Parlia) Seal(chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
- header := block.Header()
-
- // Sealing the genesis block is not supported
- number := header.Number.Uint64()
- if number == 0 {
- return errUnknownBlock
- }
- // For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing)
- if p.config.Period == 0 && len(block.Transactions()) == 0 {
- log.Info("[parlia] Sealing paused, waiting for transactions")
- return nil
- }
- // Don't hold the val fields for the entire sealing procedure
- p.signerLock.RLock()
- val, signFn := p.val, p.signFn
- p.signerLock.RUnlock()
-
- snap, err := p.snapshot(chain, number-1, header.ParentHash, nil, false /* verify */)
- if err != nil {
- return err
- }
-
- // Bail out if we're unauthorized to sign a block
- if _, authorized := snap.Validators[val]; !authorized {
- return fmt.Errorf("parlia.Seal: %w", errUnauthorizedValidator)
- }
-
- // If we're amongst the recent signers, wait for the next block
- for seen, recent := range snap.Recents {
- if recent == val {
- // Signer is among recent, only wait if the current block doesn't shift it out
- if limit := uint64(len(snap.Validators)/2 + 1); number < limit || seen > number-limit {
- log.Info("[parlia] Signed recently, must wait for others")
- return nil
- }
- }
- }
-
- // Sweet, the protocol permits us to sign the block, wait for our time
- delay := p.delayForRamanujanFork(snap, header)
-
- log.Info("Sealing block with", "number", number, "delay", delay, "headerDifficulty", header.Difficulty, "val", val.Hex(), "headerHash", header.Hash().Hex(), "gasUsed", header.GasUsed, "block txn number", block.Transactions().Len(), "State Root", header.Root)
-
- // Sign all the things!
- sig, err := signFn(val, crypto.Keccak256(parliaRLP(header, p.chainConfig.ChainID)), p.chainConfig.ChainID)
- if err != nil {
- return err
- }
- copy(header.Extra[len(header.Extra)-extraSeal:], sig)
-
- // Wait until sealing is terminated or delay timeout.
- //log.Trace("Waiting for slot to sign and propagate", "delay", common.PrettyDuration(delay))
- go func() {
- select {
- case <-stop:
- return
- case <-time.After(delay):
- }
- if p.shouldWaitForCurrentBlockProcess(p.chainDb, header, snap) {
- log.Info("[parlia] Waiting for received in turn block to process")
- select {
- case <-stop:
- log.Info("[parlia] Received block process finished, abort block seal")
- return
- case <-time.After(time.Duration(processBackOffTime) * time.Second):
- log.Info("[parlia] Process backoff time exhausted, start to seal block")
- }
- }
-
- select {
- case results <- block.WithSeal(header):
- default:
- log.Warn("[parlia] Sealing result is not read by miner", "sealhash", SealHash(header, p.chainConfig.ChainID))
- }
- }()
-
- return nil
-}
-
-// SealHash returns the hash of a block prior to it being sealed.
-func (p *Parlia) SealHash(header *types.Header) libcommon.Hash {
- return SealHash(header, p.chainConfig.ChainID)
-}
-
-// CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
-// that a new block should have.
-func (p *Parlia) CalcDifficulty(chain consensus.ChainHeaderReader, time, parentTime uint64, parentDifficulty *big.Int, parentNumber uint64, parentHash, parentUncleHash libcommon.Hash, _ uint64) *big.Int {
- snap, err := p.snapshot(chain, parentNumber, parentHash, nil, false /* verify */)
- if err != nil {
- return nil
- }
- return CalcDifficulty(snap, p.val)
-}
-
-// CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
-// that a new block should have based on the previous blocks in the chain and the
-// current signer.
-func CalcDifficulty(snap *Snapshot, signer libcommon.Address) *big.Int {
- if snap.inturn(signer) {
- return new(big.Int).Set(diffInTurn)
- }
- return new(big.Int).Set(diffNoTurn)
-}
-
-func (p *Parlia) GenerateSeal(chain consensus.ChainHeaderReader, current, parent *types.Header, call consensus.Call) []byte {
- return nil
-}
-
-// APIs returns the RPC APIs this consensus engine provides.
-func (p *Parlia) APIs(chain consensus.ChainHeaderReader) []rpc.API {
- return []rpc.API{{
- Namespace: "parlia",
- Version: "1.0",
- Service: &API{chain: chain, parlia: p},
- Public: false,
- }}
-}
-
-func (p *Parlia) IsServiceTransaction(sender libcommon.Address, syscall consensus.SystemCall) bool {
- return false
-}
-
-func (p *Parlia) IsSystemTransaction(tx types.Transaction, header *types.Header) (bool, error) {
- // deploy a contract
- if tx.GetTo() == nil {
- return false, nil
- }
- sender, err := tx.Sender(*p.signer)
- if err != nil {
- return false, errors.New("UnAuthorized transaction")
- }
- if sender == header.Coinbase && isToSystemContract(*tx.GetTo()) && tx.GetPrice().IsZero() {
- return true, nil
- }
- return false, nil
-}
-
-func isToSystemContract(to libcommon.Address) bool {
- _, ok := systemContracts[to]
- return ok
-}
-
-func (p *Parlia) IsSystemContract(to *libcommon.Address) bool {
- if to == nil {
- return false
- }
- return isToSystemContract(*to)
-}
-
-func (p *Parlia) shouldWaitForCurrentBlockProcess(chainDb kv.RwDB, header *types.Header, snap *Snapshot) bool {
- if header.Difficulty.Cmp(diffInTurn) == 0 {
- return false
- }
-
- roTx, err := chainDb.BeginRo(context.Background())
- if err != nil {
- return false
- }
- defer roTx.Rollback()
- hash := rawdb.ReadHeadHeaderHash(roTx)
- number := rawdb.ReadHeaderNumber(roTx, hash)
-
- highestVerifiedHeader := rawdb.ReadHeader(roTx, hash, *number)
- if highestVerifiedHeader == nil {
- return false
- }
-
- if header.ParentHash == highestVerifiedHeader.ParentHash {
- return true
- }
- return false
-}
-
-func (p *Parlia) EnoughDistance(chain consensus.ChainReader, header *types.Header) bool {
- snap, err := p.snapshot(chain, header.Number.Uint64()-1, header.ParentHash, nil, false /* verify */)
- if err != nil {
- return true
- }
- return snap.enoughDistance(p.val, header)
-}
-
-func (p *Parlia) IsLocalBlock(header *types.Header) bool {
- return p.val == header.Coinbase
-}
-
-func (p *Parlia) AllowLightProcess(chain consensus.ChainReader, currentHeader *types.Header) bool {
- snap, err := p.snapshot(chain, currentHeader.Number.Uint64()-1, currentHeader.ParentHash, nil, false /* verify */)
- if err != nil {
- return true
- }
-
- idx := snap.indexOfVal(p.val)
- // validator is not allowed to diff sync
- return idx < 0
-}
-
-// Close terminates any background threads maintained by the consensus engine.
-func (p *Parlia) Close() error {
- return nil
-}
-
-// ========================== interaction with contract/account =========
-
-// getCurrentValidators get current validators
-func (p *Parlia) getCurrentValidators(header *types.Header, ibs *state.IntraBlockState) ([]libcommon.Address, error) {
- // method
- var method string
- if p.chainConfig.IsEuler(header.Number) {
- method = "getMiningValidators"
- } else {
- method = "getValidators"
- }
- data, err := p.validatorSetABI.Pack(method)
- if err != nil {
- log.Error("Unable to pack tx for getValidators", "err", err)
- return nil, err
- }
- // call
- msgData := hexutility.Bytes(data)
- _, returnData, err := p.systemCall(header.Coinbase, systemcontracts.ValidatorContract, msgData[:], ibs, header, u256.Num0)
- if err != nil {
- return nil, err
- }
- var ret0 = new([]libcommon.Address)
- out := ret0
- if err := p.validatorSetABI.UnpackIntoInterface(out, method, returnData); err != nil {
- return nil, err
- }
- valz := make([]libcommon.Address, len(*ret0))
- copy(valz, *ret0)
- //for i, a := range *ret0 {
- // valz[i] = a
- //}
- return valz, nil
-}
-
-// slash spoiled validators
-func (p *Parlia) distributeIncoming(val libcommon.Address, state *state.IntraBlockState, header *types.Header,
- txs types.Transactions, receipts types.Receipts, systemTxs types.Transactions,
- usedGas *uint64, mining bool,
-) (types.Transactions, types.Transactions, types.Receipts, error) {
- coinbase := header.Coinbase
- balance := state.GetBalance(consensus.SystemAddress).Clone()
- if balance.Cmp(u256.Num0) <= 0 {
- return txs, systemTxs, receipts, nil
- }
- state.SetBalance(consensus.SystemAddress, u256.Num0)
- state.AddBalance(coinbase, balance)
-
- doDistributeSysReward := state.GetBalance(systemcontracts.SystemRewardContract).Cmp(maxSystemBalance) < 0
- if doDistributeSysReward {
- var rewards = new(uint256.Int)
- rewards = rewards.Rsh(balance, systemRewardPercent)
- if rewards.Cmp(u256.Num0) > 0 {
- var err error
- var tx types.Transaction
- var receipt *types.Receipt
- if systemTxs, tx, receipt, err = p.distributeToSystem(rewards, state, header, len(txs), systemTxs, usedGas, mining); err != nil {
- return nil, nil, nil, err
- }
- txs = append(txs, tx)
- receipts = append(receipts, receipt)
- //log.Debug("[parlia] distribute to system reward pool", "block hash", header.Hash(), "amount", rewards)
- balance = balance.Sub(balance, rewards)
- }
- }
- //log.Debug("[parlia] distribute to validator contract", "block hash", header.Hash(), "amount", balance)
- var err error
- var tx types.Transaction
- var receipt *types.Receipt
- if systemTxs, tx, receipt, err = p.distributeToValidator(balance, val, state, header, len(txs), systemTxs, usedGas, mining); err != nil {
- return nil, nil, nil, err
- }
- txs = append(txs, tx)
- receipts = append(receipts, receipt)
- return txs, systemTxs, receipts, nil
-}
-
-// slash spoiled validators
-func (p *Parlia) slash(spoiledVal libcommon.Address, state *state.IntraBlockState, header *types.Header,
- txIndex int, systemTxs types.Transactions, usedGas *uint64, mining bool,
-) (types.Transactions, types.Transaction, *types.Receipt, error) {
- // method
- method := "slash"
-
- // get packed data
- data, err := p.slashABI.Pack(method,
- spoiledVal,
- )
- if err != nil {
- log.Error("[parlia] Unable to pack tx for slash", "err", err)
- return nil, nil, nil, err
- }
- // apply message
- return p.applyTransaction(header.Coinbase, systemcontracts.SlashContract, u256.Num0, data, state, header, txIndex, systemTxs, usedGas, mining)
-}
-
-// init contract
-func (p *Parlia) initContract(state *state.IntraBlockState, header *types.Header,
- txs types.Transactions, receipts types.Receipts, systemTxs types.Transactions,
- usedGas *uint64, mining bool,
-) (types.Transactions, types.Transactions, types.Receipts, error) {
- // method
- method := "init"
- // contracts
- contracts := []libcommon.Address{
- systemcontracts.ValidatorContract,
- systemcontracts.SlashContract,
- systemcontracts.LightClientContract,
- systemcontracts.RelayerHubContract,
- systemcontracts.TokenHubContract,
- systemcontracts.RelayerIncentivizeContract,
- systemcontracts.CrossChainContract,
- }
- // get packed data
- data, err := p.validatorSetABI.Pack(method)
- if err != nil {
- log.Error("[parlia] Unable to pack tx for init validator set", "err", err)
- return nil, nil, nil, err
- }
- for _, c := range contracts {
- log.Info("[parlia] init contract", "block hash", header.Hash(), "contract", c)
- var tx types.Transaction
- var receipt *types.Receipt
- if systemTxs, tx, receipt, err = p.applyTransaction(header.Coinbase, c, u256.Num0, data, state, header, len(txs), systemTxs, usedGas, mining); err != nil {
- return nil, nil, nil, err
- }
- txs = append(txs, tx)
- receipts = append(receipts, receipt)
- }
- return txs, systemTxs, receipts, nil
-}
-
-func (p *Parlia) distributeToSystem(amount *uint256.Int, state *state.IntraBlockState, header *types.Header,
- txIndex int, systemTxs types.Transactions,
- usedGas *uint64, mining bool,
-) (types.Transactions, types.Transaction, *types.Receipt, error) {
- return p.applyTransaction(header.Coinbase, systemcontracts.SystemRewardContract, amount, nil, state, header,
- txIndex, systemTxs, usedGas, mining)
-}
-
-// slash spoiled validators
-func (p *Parlia) distributeToValidator(amount *uint256.Int, validator libcommon.Address, state *state.IntraBlockState, header *types.Header,
- txIndex int, systemTxs types.Transactions,
- usedGas *uint64, mining bool,
-) (types.Transactions, types.Transaction, *types.Receipt, error) {
- // method
- method := "deposit"
-
- // get packed data
- data, err := p.validatorSetABI.Pack(method,
- validator,
- )
- if err != nil {
- log.Error("[parlia] Unable to pack tx for deposit", "err", err)
- return nil, nil, nil, err
- }
- // apply message
- return p.applyTransaction(header.Coinbase, systemcontracts.ValidatorContract, amount, data, state, header, txIndex, systemTxs, usedGas, mining)
-}
-
-func (p *Parlia) applyTransaction(from libcommon.Address, to libcommon.Address, value *uint256.Int, data []byte, ibs *state.IntraBlockState, header *types.Header,
- txIndex int, systemTxs types.Transactions, usedGas *uint64, mining bool,
-) (types.Transactions, types.Transaction, *types.Receipt, error) {
- nonce := ibs.GetNonce(from)
- expectedTx := types.Transaction(types.NewTransaction(nonce, to, value, math.MaxUint64/2, u256.Num0, data))
- expectedHash := expectedTx.SigningHash(p.chainConfig.ChainID)
- if from == p.val && mining {
- signature, err := p.signFn(from, expectedTx.SigningHash(p.chainConfig.ChainID).Bytes(), p.chainConfig.ChainID)
- if err != nil {
- return nil, nil, nil, err
- }
- signer := types.LatestSignerForChainID(p.chainConfig.ChainID)
- expectedTx, err = expectedTx.WithSignature(*signer, signature)
- if err != nil {
- return nil, nil, nil, err
- }
- } else {
- if len(systemTxs) == 0 {
- return nil, nil, nil, fmt.Errorf("supposed to get a actual transaction, but get none")
- }
- if systemTxs[0] == nil {
- return nil, nil, nil, fmt.Errorf("supposed to get a actual transaction, but get nil")
- }
- actualTx := systemTxs[0]
- actualHash := actualTx.SigningHash(p.chainConfig.ChainID)
- if !bytes.Equal(actualHash.Bytes(), expectedHash.Bytes()) {
- return nil, nil, nil, fmt.Errorf("expected system tx (hash %v, nonce %d, to %s, value %s, gas %d, gasPrice %s, data %s), actual tx (hash %v, nonce %d, to %s, value %s, gas %d, gasPrice %s, data %s)",
- expectedHash.String(),
- expectedTx.GetNonce(),
- expectedTx.GetTo().String(),
- expectedTx.GetValue().String(),
- expectedTx.GetGas(),
- expectedTx.GetPrice().String(),
- hex.EncodeToString(expectedTx.GetData()),
- actualHash.String(),
- actualTx.GetNonce(),
- actualTx.GetTo().String(),
- actualTx.GetValue().String(),
- actualTx.GetGas(),
- actualTx.GetPrice().String(),
- hex.EncodeToString(actualTx.GetData()),
- )
- }
- expectedTx = actualTx
- // move to next
- systemTxs = systemTxs[1:]
- }
- ibs.Prepare(expectedTx.Hash(), libcommon.Hash{}, txIndex)
- gasUsed, _, err := p.systemCall(from, to, data, ibs, header, value)
- if err != nil {
- return nil, nil, nil, err
- }
- *usedGas += gasUsed
- receipt := types.NewReceipt(false, *usedGas)
- receipt.TxHash = expectedTx.Hash()
- receipt.GasUsed = gasUsed
- if err := ibs.FinalizeTx(p.chainConfig.Rules(header.Number.Uint64(), header.Time), state.NewNoopWriter()); err != nil {
- return nil, nil, nil, err
- }
- // Set the receipt logs and create a bloom for filtering
- receipt.Logs = ibs.GetLogs(expectedTx.Hash())
- receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
- receipt.BlockHash = header.Hash()
- receipt.BlockNumber = header.Number
- receipt.TransactionIndex = uint(txIndex)
- ibs.SetNonce(from, nonce+1)
- return systemTxs, expectedTx, receipt, nil
-}
-
-func (p *Parlia) systemCall(from, contract libcommon.Address, data []byte, ibs *state.IntraBlockState, header *types.Header, value *uint256.Int) (gasUsed uint64, returnData []byte, err error) {
- chainConfig := p.chainConfig
- if chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(header.Number) == 0 {
- misc.ApplyDAOHardFork(ibs)
- }
- msg := types.NewMessage(
- from,
- &contract,
- 0, value,
- math.MaxUint64/2, u256.Num0,
- nil, nil,
- data, nil, false,
- true, // isFree
- )
- vmConfig := vm.Config{NoReceipts: true}
- // Create a new context to be used in the EVM environment
- blockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, nil), p, &from, nil /*excessDataGas*/)
- evm := vm.NewEVM(blockContext, core.NewEVMTxContext(msg), ibs, chainConfig, vmConfig)
- ret, leftOverGas, err := evm.Call(
- vm.AccountRef(msg.From()),
- *msg.To(),
- msg.Data(),
- msg.Gas(),
- msg.Value(),
- false,
- )
- if err != nil {
- return 0, nil, err
- }
- return msg.Gas() - leftOverGas, ret, nil
-}
diff --git a/consensus/parlia/ramanujanfork.go b/consensus/parlia/ramanujanfork.go
deleted file mode 100644
index fbc77b9e4..000000000
--- a/consensus/parlia/ramanujanfork.go
+++ /dev/null
@@ -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
-}
diff --git a/consensus/parlia/snapshot.go b/consensus/parlia/snapshot.go
deleted file mode 100644
index 1c3c70076..000000000
--- a/consensus/parlia/snapshot.go
+++ /dev/null
@@ -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 .
-
-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
-}
diff --git a/consensus/parlia/snapshot_test.go b/consensus/parlia/snapshot_test.go
deleted file mode 100644
index 160408d6f..000000000
--- a/consensus/parlia/snapshot_test.go
+++ /dev/null
@@ -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)
-}
diff --git a/consensus/parlia/utils.go b/consensus/parlia/utils.go
deleted file mode 100644
index 6740131d0..000000000
--- a/consensus/parlia/utils.go
+++ /dev/null
@@ -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
- }
-}
diff --git a/core/blockchain.go b/core/blockchain.go
index 11006f7c4..b6174c9c0 100644
--- a/core/blockchain.go
+++ b/core/blockchain.go
@@ -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(
diff --git a/core/state_transition.go b/core/state_transition.go
index 30c78260d..965ac8486 100644
--- a/core/state_transition.go
+++ b/core/state_transition.go
@@ -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)
diff --git a/core/types/accounts/account.go b/core/types/accounts/account.go
index e5f65e20f..2512f48c3 100644
--- a/core/types/accounts/account.go
+++ b/core/types/accounts/account.go
@@ -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"
)
diff --git a/core/vm/contracts.go b/core/vm/contracts.go
index c3a4beb23..1d8c86ec0 100644
--- a/core/vm/contracts.go
+++ b/core/vm/contracts.go
@@ -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
diff --git a/core/vm/contracts_lightclient.go b/core/vm/contracts_lightclient.go
deleted file mode 100644
index e6b11d5e7..000000000
--- a/core/vm/contracts_lightclient.go
+++ /dev/null
@@ -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
-}
diff --git a/core/vm/contracts_lightclient_test.go b/core/vm/contracts_lightclient_test.go
deleted file mode 100644
index ef5857904..000000000
--- a/core/vm/contracts_lightclient_test.go
+++ /dev/null
@@ -1,197 +0,0 @@
-package vm
-
-import (
- "encoding/binary"
- "encoding/hex"
- "github.com/stretchr/testify/assert"
- "testing"
-
- "github.com/stretchr/testify/require"
-
- "github.com/ledgerwatch/erigon/core/vm/lightclient"
-)
-
-const (
- testHeight uint64 = 66848226
-)
-
-func TestTmHeaderValidateAndMerkleProofValidate(t *testing.T) {
- consensusStateBytes, err := hex.DecodeString("42696e616e63652d436861696e2d4e696c650000000000000000000000000000000000000" +
- "3fc05e2b7029751d2a6581efc2f79712ec44d8b4981850325a7feadaa58ef4ddaa18a9380d9ab0fc10d18ca0e0832d5f4c063c5489ec1443dfb738" +
- "252d038a82131b27ae17cbe9c20cdcfdf876b3b12978d3264a007fcaaa71c4cdb701d9ebc0323f44f000000174876e800184e7b103d34c41003f9b" +
- "864d5f8c1adda9bd0436b253bb3c844bc739c1e77c9000000174876e8004d420aea843e92a0cfe69d89696dff6827769f9cb52a249af537ce89bf2" +
- "a4b74000000174876e800bd03de9f8ab29e2800094e153fac6f696cfa512536c9c2f804dcb2c2c4e4aed6000000174876e8008f4a74a07351895dd" +
- "f373057b98fae6dfaf2cd21f37a063e19601078fe470d53000000174876e8004a5d4753eb79f92e80efe22df7aca4f666a4f44bf81c536c4a09d4b" +
- "9c5b654b5000000174876e800c80e9abef7ff439c10c68fe8f1303deddfc527718c3b37d8ba6807446e3c827a000000174876e8009142afcc691b7" +
- "cc05d26c7b0be0c8b46418294171730e079f384fde2fa50bafc000000174876e80049b288e4ebbb3a281c2d546fc30253d5baf08993b6e5d295fb7" +
- "87a5b314a298e000000174876e80004224339688f012e649de48e241880092eaa8f6aa0f4f14bfcf9e0c76917c0b6000000174876e8004034b37ce" +
- "da8a0bf13b1abaeee7a8f9383542099a554d219b93d0ce69e3970e8000000174876e800")
- require.NoError(t, err)
-
- cs, err := lightclient.DecodeConsensusState(consensusStateBytes)
- require.NoError(t, err)
-
- headerBytes, err := hex.DecodeString("e3210a92130abb020a02080a121242696e616e63652d436861696e2d4e696c6518e38bf01f220c08e191aef20510f5f4e4c70230dae0c7173a480a20102b54820dd8fb5bc2c4e875ee573fa294d9b7b7ceb362aa8fd21b33dee41b1c12240801122082f341511f3e6b89d6177fd31f8a106013ba09d6e12ef40a7dec885d81b687634220b1b77e6977e0cd0177e3102a78833c9e152aa646ed4fb5a77e8af58c9867eec0522080d9ab0fc10d18ca0e0832d5f4c063c5489ec1443dfb738252d038a82131b27a5a2080d9ab0fc10d18ca0e0832d5f4c063c5489ec1443dfb738252d038a82131b27a6220294d8fbd0b94b767a7eba9840f299a3586da7fe6b5dead3b7eecba193c400f936a20a3e248bc209955054d880e4d89ff3c0419c0cd77681f4b4c6649ead5545054b982011462633d9db7ed78e951f79913fdc8231aa77ec12b12d1100a480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be212b601080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510cebfe23e321406fd60078eb4c2356137dd50036597db267cf61642409276f20ad4b152f91c344bd63ac691bad66e04e228a8b58dca293ff0bd10f8aef6dfbcecae49e32b09d89e10b771a6c01628628596a95e126b04763560c66c0f12b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510a4caa532321418e69cc672973992bb5f76d049a5b2c5ddf77436380142409ed2b74fa835296d552e68c439dd4ee3fa94fb197282edcc1cc815c863ca42a2c9a73475ff6be9064371a61655a3c31d2f0acc89c3a4489ad4c2671aef52360512b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510a69eca2f3214344c39bb8f4512d6cab1f6aafac1811ef9d8afdf38024240de2768ead90011bcbb1914abc1572749ab7b81382eb81cff3b41c56edc12470a7b8a4d61f8b4ca7b2cb7e24706edd219455796b4db74cd36965859f91dc8910312b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510dcdd833b321437ef19af29679b368d2b9e9de3f8769b357866763803424072ddfe0aeb13616b3f17eb60b19a923ec51fcc726625094aa069255c829c8cdd9e242080a1e559b0030fe9a0db19fd34e392bd78df12a9caff9f2b811bc1ac0a12b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510e9f2f859321462633d9db7ed78e951f79913fdc8231aa77ec12b38044240f5f61c640ab2402b44936de0d24e7b439df78bc3ef15467ecb29b92ece4aa0550790d5ce80761f2ac4b0e3283969725c42343749d9b44b179b2d4fced66c5d0412b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510ff90f55532147b343e041ca130000a8bc00c35152bd7e774003738054240df6e298b3efd42eb536e68a0210bc921e8b5dc145fe965f63f4d3490064f239f2a54a6db16c96086e4ae52280c04ad8b32b44f5ff3d41f0c364949ccb628c50312b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510cad7c931321491844d296bd8e591448efc65fd6ad51a888d58fa3806424030298627da1afd28229aac150f553724b594989e59136d6a175d84e45a4dee344ff9e0eeb69fdf29abb6d833adc3e1ccdc87b2a65019ef5fb627c44d9d132c0012b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510c8c296323214b3727172ce6473bc780298a2d66c12f1a14f5b2a38074240918491100730b4523f0c85409f6d1cca9ebc4b8ca6df8d55fe3d85158fa43286608693c50332953e1d3b93e3e78b24e158d6a2275ce8c6c7c07a7a646a19200312b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef2051086f1a2403214b6f20c7faa2b2f6f24518fa02b71cb5f4a09fba338084240ca59c9fc7f6ab660e9970fc03e5ed588ccb8be43fe5a3e8450287b726f29d039e53fe888438f178ac63c3d2ca969cd8c2fbc8606f067634339b6a94a7382960212b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef2051080efbb543214e0dd72609cc106210d1aa13936cb67b93a0aee2138094240e787a21f5cb7052624160759a9d379dd9db144f2b498bca026375c9ce8ecdc2a0936af1c309b3a0f686c92bf5578b595a4ca99036a19c9fc50d3718fd454b30012b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510ddf8d85a3214fc3108dc3814888f4187452182bc1baf83b71bc9380a4240d51ea31f6449eed71de22339722af1edbb0b21401037d85882b32a2ed8ae9127f2df4d1da2092729e582812856227ed6cdf98a3f60203d1ff80bd635fb03bb0912a4070a4f0a1406fd60078eb4c2356137dd50036597db267cf61612251624de6420e17cbe9c20cdcfdf876b3b12978d3264a007fcaaa71c4cdb701d9ebc0323f44f1880d0dbc3f4022080e0ebdaf2e2ffffff010a4b0a1418e69cc672973992bb5f76d049a5b2c5ddf7743612251624de6420184e7b103d34c41003f9b864d5f8c1adda9bd0436b253bb3c844bc739c1e77c91880d0dbc3f4022080d0dbc3f4020a4b0a14344c39bb8f4512d6cab1f6aafac1811ef9d8afdf12251624de64204d420aea843e92a0cfe69d89696dff6827769f9cb52a249af537ce89bf2a4b741880d0dbc3f4022080d0dbc3f4020a4b0a1437ef19af29679b368d2b9e9de3f8769b3578667612251624de6420bd03de9f8ab29e2800094e153fac6f696cfa512536c9c2f804dcb2c2c4e4aed61880d0dbc3f4022080d0dbc3f4020a4b0a1462633d9db7ed78e951f79913fdc8231aa77ec12b12251624de64208f4a74a07351895ddf373057b98fae6dfaf2cd21f37a063e19601078fe470d531880d0dbc3f4022080d0dbc3f4020a4b0a147b343e041ca130000a8bc00c35152bd7e774003712251624de64204a5d4753eb79f92e80efe22df7aca4f666a4f44bf81c536c4a09d4b9c5b654b51880d0dbc3f4022080d0dbc3f4020a4b0a1491844d296bd8e591448efc65fd6ad51a888d58fa12251624de6420c80e9abef7ff439c10c68fe8f1303deddfc527718c3b37d8ba6807446e3c827a1880d0dbc3f4022080d0dbc3f4020a4b0a14b3727172ce6473bc780298a2d66c12f1a14f5b2a12251624de64209142afcc691b7cc05d26c7b0be0c8b46418294171730e079f384fde2fa50bafc1880d0dbc3f4022080d0dbc3f4020a4b0a14b6f20c7faa2b2f6f24518fa02b71cb5f4a09fba312251624de642049b288e4ebbb3a281c2d546fc30253d5baf08993b6e5d295fb787a5b314a298e1880d0dbc3f4022080d0dbc3f4020a4b0a14e0dd72609cc106210d1aa13936cb67b93a0aee2112251624de642004224339688f012e649de48e241880092eaa8f6aa0f4f14bfcf9e0c76917c0b61880d0dbc3f4022080d0dbc3f4020a4b0a14fc3108dc3814888f4187452182bc1baf83b71bc912251624de64204034b37ceda8a0bf13b1abaeee7a8f9383542099a554d219b93d0ce69e3970e81880d0dbc3f4022080d0dbc3f402124f0a1406fd60078eb4c2356137dd50036597db267cf61612251624de6420e17cbe9c20cdcfdf876b3b12978d3264a007fcaaa71c4cdb701d9ebc0323f44f1880d0dbc3f4022080e0ebdaf2e2ffffff011aa4070a4f0a1406fd60078eb4c2356137dd50036597db267cf61612251624de6420e17cbe9c20cdcfdf876b3b12978d3264a007fcaaa71c4cdb701d9ebc0323f44f1880d0dbc3f4022080e0ebdaf2e2ffffff010a4b0a1418e69cc672973992bb5f76d049a5b2c5ddf7743612251624de6420184e7b103d34c41003f9b864d5f8c1adda9bd0436b253bb3c844bc739c1e77c91880d0dbc3f4022080d0dbc3f4020a4b0a14344c39bb8f4512d6cab1f6aafac1811ef9d8afdf12251624de64204d420aea843e92a0cfe69d89696dff6827769f9cb52a249af537ce89bf2a4b741880d0dbc3f4022080d0dbc3f4020a4b0a1437ef19af29679b368d2b9e9de3f8769b3578667612251624de6420bd03de9f8ab29e2800094e153fac6f696cfa512536c9c2f804dcb2c2c4e4aed61880d0dbc3f4022080d0dbc3f4020a4b0a1462633d9db7ed78e951f79913fdc8231aa77ec12b12251624de64208f4a74a07351895ddf373057b98fae6dfaf2cd21f37a063e19601078fe470d531880d0dbc3f4022080d0dbc3f4020a4b0a147b343e041ca130000a8bc00c35152bd7e774003712251624de64204a5d4753eb79f92e80efe22df7aca4f666a4f44bf81c536c4a09d4b9c5b654b51880d0dbc3f4022080d0dbc3f4020a4b0a1491844d296bd8e591448efc65fd6ad51a888d58fa12251624de6420c80e9abef7ff439c10c68fe8f1303deddfc527718c3b37d8ba6807446e3c827a1880d0dbc3f4022080d0dbc3f4020a4b0a14b3727172ce6473bc780298a2d66c12f1a14f5b2a12251624de64209142afcc691b7cc05d26c7b0be0c8b46418294171730e079f384fde2fa50bafc1880d0dbc3f4022080d0dbc3f4020a4b0a14b6f20c7faa2b2f6f24518fa02b71cb5f4a09fba312251624de642049b288e4ebbb3a281c2d546fc30253d5baf08993b6e5d295fb787a5b314a298e1880d0dbc3f4022080d0dbc3f4020a4b0a14e0dd72609cc106210d1aa13936cb67b93a0aee2112251624de642004224339688f012e649de48e241880092eaa8f6aa0f4f14bfcf9e0c76917c0b61880d0dbc3f4022080d0dbc3f4020a4b0a14fc3108dc3814888f4187452182bc1baf83b71bc912251624de64204034b37ceda8a0bf13b1abaeee7a8f9383542099a554d219b93d0ce69e3970e81880d0dbc3f4022080d0dbc3f402124f0a1406fd60078eb4c2356137dd50036597db267cf61612251624de6420e17cbe9c20cdcfdf876b3b12978d3264a007fcaaa71c4cdb701d9ebc0323f44f1880d0dbc3f4022080e0ebdaf2e2ffffff01")
- require.NoError(t, err)
-
- parameterInput := make([]byte, 32+len(consensusStateBytes)+len(headerBytes))
- binary.BigEndian.PutUint64(parameterInput[24:32], uint64(len(consensusStateBytes)))
- copy(parameterInput[32:32+len(consensusStateBytes)], consensusStateBytes)
- copy(parameterInput[32+len(consensusStateBytes):], headerBytes)
-
- totalLengthPrefix := make([]byte, 32)
- binary.BigEndian.PutUint64(totalLengthPrefix[0:8], 0)
- binary.BigEndian.PutUint64(totalLengthPrefix[8:16], 0)
- binary.BigEndian.PutUint64(totalLengthPrefix[16:24], 0)
- binary.BigEndian.PutUint64(totalLengthPrefix[24:], uint64(len(parameterInput)))
- input := append(totalLengthPrefix, parameterInput...)
-
- var tmHeaderValidateContract tmHeaderValidate
- syncedConsensusStateBytes, err := tmHeaderValidateContract.Run(input)
- require.NoError(t, err)
- syncedConsensusState, err := lightclient.DecodeConsensusState(syncedConsensusStateBytes[32:])
- require.NoError(t, err)
- require.Equal(t, testHeight+1, syncedConsensusState.Height)
- require.Equal(t, cs.ChainID, syncedConsensusState.ChainID)
-
- headerBytes, err = hex.DecodeString("c11d0af00e0aba020a02080a121242696e616e63652d436861696e2d4e696c65188596a822220b08bd85c2f30510e8f3d65730a986f7173a480a209e4b742cb3d59618c5af9d9b9d8b6a8408802131a968c6d1e3a516c9548cedc01224080112201dd8f3e89b01db52d79f89a87c8abfe9836e8b828ed33d78e202664dfead9c0e422018c8c46d7665a5db717331ff3deebe8f9986352d308c5950cf1a09286439dd9d522080d9ab0fc10d18ca0e0832d5f4c063c5489ec1443dfb738252d038a82131b27a5a2080d9ab0fc10d18ca0e0832d5f4c063c5489ec1443dfb738252d038a82131b27a6220294d8fbd0b94b767a7eba9840f299a3586da7fe6b5dead3b7eecba193c400f936a202c69c314b4de5c8035253c8bc0771d9ca17b1b23a57c0c6d068b57579791cae2820114b3727172ce6473bc780298a2d66c12f1a14f5b2a12b00c0a480a20c24c5e913fe4b8eec95d473d671c2dfc2cf651118b37e83661a24a1b8ef842251224080112206310a09cbcf41fd71c55e524c7a91f71414bb31ecf6e7b74161e8ec04a3c7b2b120012b9010802108596a82222480a20c24c5e913fe4b8eec95d473d671c2dfc2cf651118b37e83661a24a1b8ef842251224080112206310a09cbcf41fd71c55e524c7a91f71414bb31ecf6e7b74161e8ec04a3c7b2b2a0c08bd85c2f30510cff5c5a102321418e69cc672973992bb5f76d049a5b2c5ddf7743638014240129b1ac9bcf178022f358161f90a0c83d8344be7ad7e1f55c98b4a7f366a95816e80a7e2beac669c73fa5bd6e17693f8a70347ab785c7883a8ef2c9d7464b50a12b9010802108596a82222480a20c24c5e913fe4b8eec95d473d671c2dfc2cf651118b37e83661a24a1b8ef842251224080112206310a09cbcf41fd71c55e524c7a91f71414bb31ecf6e7b74161e8ec04a3c7b2b2a0c08bd85c2f30510e3f7919d023214344c39bb8f4512d6cab1f6aafac1811ef9d8afdf38024240ad6d56ffd8062b70f6c2bf7345a26fcb0a5de2bc477d21e71d780c7f029098aba7efaa2aae1b945602c22d0d1ccdec1e45e7d14d177677a2ba23feeffa88c103120012b9010802108596a82222480a20c24c5e913fe4b8eec95d473d671c2dfc2cf651118b37e83661a24a1b8ef842251224080112206310a09cbcf41fd71c55e524c7a91f71414bb31ecf6e7b74161e8ec04a3c7b2b2a0c08bd85c2f305109c88b58202321462633d9db7ed78e951f79913fdc8231aa77ec12b3804424017c205e1eade76097e659a2c3a20bd7fc61e383b5b631499a8bf26ac81c537d7369ddc5be0c4f8a62c6cfb55d5d6cd4ce75aa57c03888aef365d0702032e6d0c12b9010802108596a82222480a20c24c5e913fe4b8eec95d473d671c2dfc2cf651118b37e83661a24a1b8ef842251224080112206310a09cbcf41fd71c55e524c7a91f71414bb31ecf6e7b74161e8ec04a3c7b2b2a0c08bd85c2f30510bcbda5ff0132147b343e041ca130000a8bc00c35152bd7e7740037380542404c8536a8a2af12e88176699c93ee6c9032240b58b6f92897a7724bd41447f81ae8533e2e3676a44d398296006c1d51d14c9eb2ebca5ac02a5925c549de571b0012b9010802108596a82222480a20c24c5e913fe4b8eec95d473d671c2dfc2cf651118b37e83661a24a1b8ef842251224080112206310a09cbcf41fd71c55e524c7a91f71414bb31ecf6e7b74161e8ec04a3c7b2b2a0c08bd85c2f30510968bff9c02321491844d296bd8e591448efc65fd6ad51a888d58fa38064240f1b55166334e16b2cf1e6bf35521a17b6fc8699807df66495c14508ed5c75b27bf0ba19f7ad4302166d673f027a37148f6ecf4b87fe60b6f196bfc944df3c90412b9010802108596a82222480a20c24c5e913fe4b8eec95d473d671c2dfc2cf651118b37e83661a24a1b8ef842251224080112206310a09cbcf41fd71c55e524c7a91f71414bb31ecf6e7b74161e8ec04a3c7b2b2a0c08bd85c2f30510899ab59f023214b3727172ce6473bc780298a2d66c12f1a14f5b2a38074240b90deb286343c378597d36c381b11f720b9994cc4aefb28ebe840240bd68b4e8855b8508f072133e36a92f4160e5172dd4e086cde6799dc957e3d971784a130e120012b9010802108596a82222480a20c24c5e913fe4b8eec95d473d671c2dfc2cf651118b37e83661a24a1b8ef842251224080112206310a09cbcf41fd71c55e524c7a91f71414bb31ecf6e7b74161e8ec04a3c7b2b2a0c08bd85c2f30510e7c1dffe013214e0dd72609cc106210d1aa13936cb67b93a0aee213809424085424cd5908cc12b9ce35b4891f20af1791f5a7a8f7dfef225a790890a1639badef168a57005ad64d167faf86c97c4bdfeba1d5307182abeb4ef768b4056c00d12b9010802108596a82222480a20c24c5e913fe4b8eec95d473d671c2dfc2cf651118b37e83661a24a1b8ef842251224080112206310a09cbcf41fd71c55e524c7a91f71414bb31ecf6e7b74161e8ec04a3c7b2b2a0c08bd85c2f305108bd8c5ff013214fc3108dc3814888f4187452182bc1baf83b71bc9380a424013382f84fa5d21f6a274159300b5fb20e21705c80b45beff6ca48d84ffa7ab700275e8017bcf69ac70f0c76bd497977c7373e3a9cfdfc09355cf5427272e4d0512a4070a4f0a1406fd60078eb4c2356137dd50036597db267cf61612251624de6420e17cbe9c20cdcfdf876b3b12978d3264a007fcaaa71c4cdb701d9ebc0323f44f1880d0dbc3f4022080e0ebdaf2e2ffffff010a4b0a1418e69cc672973992bb5f76d049a5b2c5ddf7743612251624de6420184e7b103d34c41003f9b864d5f8c1adda9bd0436b253bb3c844bc739c1e77c91880d0dbc3f4022080d0dbc3f4020a4b0a14344c39bb8f4512d6cab1f6aafac1811ef9d8afdf12251624de64204d420aea843e92a0cfe69d89696dff6827769f9cb52a249af537ce89bf2a4b741880d0dbc3f4022080d0dbc3f4020a4b0a1437ef19af29679b368d2b9e9de3f8769b3578667612251624de6420bd03de9f8ab29e2800094e153fac6f696cfa512536c9c2f804dcb2c2c4e4aed61880d0dbc3f4022080d0dbc3f4020a4b0a1462633d9db7ed78e951f79913fdc8231aa77ec12b12251624de64208f4a74a07351895ddf373057b98fae6dfaf2cd21f37a063e19601078fe470d531880d0dbc3f4022080d0dbc3f4020a4b0a147b343e041ca130000a8bc00c35152bd7e774003712251624de64204a5d4753eb79f92e80efe22df7aca4f666a4f44bf81c536c4a09d4b9c5b654b51880d0dbc3f4022080d0dbc3f4020a4b0a1491844d296bd8e591448efc65fd6ad51a888d58fa12251624de6420c80e9abef7ff439c10c68fe8f1303deddfc527718c3b37d8ba6807446e3c827a1880d0dbc3f4022080d0dbc3f4020a4b0a14b3727172ce6473bc780298a2d66c12f1a14f5b2a12251624de64209142afcc691b7cc05d26c7b0be0c8b46418294171730e079f384fde2fa50bafc1880d0dbc3f4022080d0dbc3f4020a4b0a14b6f20c7faa2b2f6f24518fa02b71cb5f4a09fba312251624de642049b288e4ebbb3a281c2d546fc30253d5baf08993b6e5d295fb787a5b314a298e1880d0dbc3f4022080d0dbc3f4020a4b0a14e0dd72609cc106210d1aa13936cb67b93a0aee2112251624de642004224339688f012e649de48e241880092eaa8f6aa0f4f14bfcf9e0c76917c0b61880d0dbc3f4022080d0dbc3f4020a4b0a14fc3108dc3814888f4187452182bc1baf83b71bc912251624de64204034b37ceda8a0bf13b1abaeee7a8f9383542099a554d219b93d0ce69e3970e81880d0dbc3f4022080d0dbc3f402124f0a1406fd60078eb4c2356137dd50036597db267cf61612251624de6420e17cbe9c20cdcfdf876b3b12978d3264a007fcaaa71c4cdb701d9ebc0323f44f1880d0dbc3f4022080e0ebdaf2e2ffffff011aa4070a4f0a1406fd60078eb4c2356137dd50036597db267cf61612251624de6420e17cbe9c20cdcfdf876b3b12978d3264a007fcaaa71c4cdb701d9ebc0323f44f1880d0dbc3f4022080e0ebdaf2e2ffffff010a4b0a1418e69cc672973992bb5f76d049a5b2c5ddf7743612251624de6420184e7b103d34c41003f9b864d5f8c1adda9bd0436b253bb3c844bc739c1e77c91880d0dbc3f4022080d0dbc3f4020a4b0a14344c39bb8f4512d6cab1f6aafac1811ef9d8afdf12251624de64204d420aea843e92a0cfe69d89696dff6827769f9cb52a249af537ce89bf2a4b741880d0dbc3f4022080d0dbc3f4020a4b0a1437ef19af29679b368d2b9e9de3f8769b3578667612251624de6420bd03de9f8ab29e2800094e153fac6f696cfa512536c9c2f804dcb2c2c4e4aed61880d0dbc3f4022080d0dbc3f4020a4b0a1462633d9db7ed78e951f79913fdc8231aa77ec12b12251624de64208f4a74a07351895ddf373057b98fae6dfaf2cd21f37a063e19601078fe470d531880d0dbc3f4022080d0dbc3f4020a4b0a147b343e041ca130000a8bc00c35152bd7e774003712251624de64204a5d4753eb79f92e80efe22df7aca4f666a4f44bf81c536c4a09d4b9c5b654b51880d0dbc3f4022080d0dbc3f4020a4b0a1491844d296bd8e591448efc65fd6ad51a888d58fa12251624de6420c80e9abef7ff439c10c68fe8f1303deddfc527718c3b37d8ba6807446e3c827a1880d0dbc3f4022080d0dbc3f4020a4b0a14b3727172ce6473bc780298a2d66c12f1a14f5b2a12251624de64209142afcc691b7cc05d26c7b0be0c8b46418294171730e079f384fde2fa50bafc1880d0dbc3f4022080d0dbc3f4020a4b0a14b6f20c7faa2b2f6f24518fa02b71cb5f4a09fba312251624de642049b288e4ebbb3a281c2d546fc30253d5baf08993b6e5d295fb787a5b314a298e1880d0dbc3f4022080d0dbc3f4020a4b0a14e0dd72609cc106210d1aa13936cb67b93a0aee2112251624de642004224339688f012e649de48e241880092eaa8f6aa0f4f14bfcf9e0c76917c0b61880d0dbc3f4022080d0dbc3f4020a4b0a14fc3108dc3814888f4187452182bc1baf83b71bc912251624de64204034b37ceda8a0bf13b1abaeee7a8f9383542099a554d219b93d0ce69e3970e81880d0dbc3f4022080d0dbc3f402124f0a1406fd60078eb4c2356137dd50036597db267cf61612251624de6420e17cbe9c20cdcfdf876b3b12978d3264a007fcaaa71c4cdb701d9ebc0323f44f1880d0dbc3f4022080e0ebdaf2e2ffffff01")
- require.NoError(t, err)
-
- syncedConsensusStateBytes = syncedConsensusStateBytes[32:]
- parameterInput = make([]byte, 32+len(syncedConsensusStateBytes)+len(headerBytes))
- binary.BigEndian.PutUint64(parameterInput[24:32], uint64(len(syncedConsensusStateBytes)))
- copy(parameterInput[32:32+len(syncedConsensusStateBytes)], syncedConsensusStateBytes)
- copy(parameterInput[32+len(syncedConsensusStateBytes):], headerBytes)
-
- totalLengthPrefix = make([]byte, 32)
- binary.BigEndian.PutUint64(totalLengthPrefix[24:32], uint64(len(parameterInput)))
- input = append(totalLengthPrefix, parameterInput...)
-
- syncedAgainConsensusStateBytes, err := tmHeaderValidateContract.Run(input)
- require.NoError(t, err)
- syncedAgainConsensusState, err := lightclient.DecodeConsensusState(syncedAgainConsensusStateBytes[32:])
- require.NoError(t, err)
-
- newAppHash := syncedAgainConsensusState.AppHash
- key, err := hex.DecodeString("6163636f756e743a8a4e2eb018bdf98a8f53ec755740ffc728637a1d")
- require.NoError(t, err)
- value, err := hex.DecodeString("4bdc4c270a750a148a4e2eb018bdf98a8f53ec755740ffc728637a1d12110a0941544348412d3733301080f69bf321120b0a03424e4210e8baeb8d44120f0a075050432d303041108094ebdc031a26eb5ae98721031c199c92e5b0080967da99be27cf2da53317441b4a663e6d9c6caf02be1fdbdc20d7962b2815")
- require.NoError(t, err)
- proofBytes, err := hex.DecodeString("0add070a066961766c3a76121c6163636f756e743a8a4e2eb018bdf98a8f53ec755740ffc728637a1d1ab407b2070aaf070a2d081810cdfd2b188096a82222209f223f804e2d94ac51c4321b0687397012e6d95eb9783b03bc790da631004c7c0a2d081710adb31a18f395a8222a20d2a38865de82383ccce0140513b65cec1bf2ae6cd7dfeb22eb6faadb4e26b26f0a2d081510b2990b18f395a82222208a02bbd5a695dfc772627ac8744aa9cf30ae26575bdce8c96a9a0d0999175b430a2d081410e6ff0418f395a8222a20d39619c779be909e67f23499fb74eb2c19afd7f21523401d4ccf7e917db5cd600a2d081210e3fe0118f395a8222a20a10cc73843f889d9e03a463eb135e928bb980e19734344cba0fbf4e8a4c5258b0a2c081010dd6518f395a8222a2007fd15843a2fd3f58d021b0e072a6c70742d7a3d993a922445e3491e1c14ee8e0a2c080f10cc2a18eda6a7222a20088942d7b30abd021d8e9505cc41313fad87c8c10a799f3b51018b7b2cfe4ad90a2c080d10b70d18eda6a7222a2091a37bc44d0c61e3752ddc59eb390355ab65e8a9fb453be4f0acec537f1ca14f0a2c080c10890818eda6a72222201cfc317855a06667c45812fe36efe33af05671dfe0d9b56b02662011af2e79e30a2c080b10ac0318c4b0ee212220aeb454a4b3243b6269a2fd8841dca9a951c53b30f1e27da91063dae7224402c70a2c080910e40118c4b0ee212a20441340a4de6498f861b97b3f3ad9603af055e5af51a0d96fff2ae28e3c5c6c9a0a2c0808108d0118c4b0ee212220ae32ea4b9ab7b53571da320e2815fd8b2c278124961cca4a1849a799842424450a2b0807104d18c4b0ee212220e2804c9b7f045ec0b4ab20920a937b82fda8b7a9ddd12b21637335b915cfda550a2b0806102418a5f4c7192a20ec85f22addedfc82c771af5b4c77544b7c1d7c5bbac33f2712dfba1045ebdbd00a2b0805101118a5f4c7192a2071ade34dcc447a0ba8adc603080633d15c06f3525830c86ebce35eca0a4921fc0a2b0804100c18a5f4c7192a205190bce93993e65b266a3417ed511df8897a812cb4b62569e5afcfbec10b69cd0a2b0803100618a5f4c7192220b76c6884f1d412ac10bfb3987fb7d26f0330b2a85539509ebc5c6bdec2f95d520a2b0802100418a5f4c71922206a285b4a4f9d1c687bbafa1f3649b6a6e32b1a85dd0402421210683e846cf0020a2b0801100218a5f4c7192220033b3f7c6dcb258b6e55545e7a4f51539447cd595eb8a2e373ba0015502da1051a450a1c6163636f756e743a8a4e2eb018bdf98a8f53ec755740ffc728637a1d12201a272295e94cf1d8090bdb019dde48e9dab026ad2c3e43aaa7e61cc954a9245d18a5f4c7190ab6040a0a6d756c746973746f726512036163631aa204a0040a9d040a300a0364657812290a27088496a822122038fc49f49648fec62acc434151a51eaa378c1b20a730a749548e36f1529422500a300a03676f7612290a27088496a8221220a78ce489bdf08b9ee869c184876e1623dc38b3e64a5cf1a0005f97976c64deac0a380a0b61746f6d69635f7377617012290a27088496a8221220544c2fa38f61e10a39ec00b3e724d5834761268bb455cdbf5843bcf1531f8fbc0a300a0376616c12290a27088496a82212201f71082c9f6f45fb456b2c00b41e50d2f662f2dfec3cb6965f19d214bf02f3980a0f0a046d61696e12070a05088496a8220a320a057374616b6512290a27088496a82212200dd467343c718f240e50b4feac42970fc8c1c69a018be955f9c27913ac1f8b3c0a300a0361636312290a27088496a8221220270c19ccc9c40c5176b3dfbd8af734c97a307e0dbd8df9e286dcd5d709f973ed0a330a06746f6b656e7312290a27088496a8221220c4f96eedf50c83964de9df013afec2e545012d92528b643a5166c828774187b60a320a05706169727312290a27088496a8221220351c55cfda84596ecd22ebc77013662aba97f81f19d9ef3d150213bb07c823060a360a0974696d655f6c6f636b12290a27088496a8221220e7adf5bd30ce022decf0e9341bf05c464ed70cdbc97423bd2bab8f3571e5179b0a330a06706172616d7312290a27088496a822122042a9dfc356ca435db131eb41fb1975c8482f2434537918665e530b0b4633b5f9")
- require.NoError(t, err)
-
- merkleProofInput := make([]byte, 32+32+len(key)+32+len(value)+32+len(proofBytes))
- copy(merkleProofInput[:32], "acc")
- binary.BigEndian.PutUint64(merkleProofInput[32+24:32+32], uint64(len(key)))
- copy(merkleProofInput[32+32:32+32+len(key)], key)
-
- binary.BigEndian.PutUint64(merkleProofInput[32+32+len(key)+24:32+32+len(key)+32], uint64(len(value)))
- copy(merkleProofInput[32+32+len(key)+32:32+32+len(key)+32+len(value)], value)
-
- copy(merkleProofInput[32+32+len(key)+32+len(value):32+32+len(key)+32+len(value)+32], newAppHash)
- copy(merkleProofInput[32+32+len(key)+32+len(value)+32:], proofBytes)
-
- totalLengthPrefix = make([]byte, 32)
- binary.BigEndian.PutUint64(totalLengthPrefix[0:8], 0)
- binary.BigEndian.PutUint64(totalLengthPrefix[8:16], 0)
- binary.BigEndian.PutUint64(totalLengthPrefix[16:24], 0)
- binary.BigEndian.PutUint64(totalLengthPrefix[24:], uint64(len(merkleProofInput)))
- input = append(totalLengthPrefix, merkleProofInput...)
-
- iavlMerkleProofValidateContract := iavlMerkleProofValidate{}
- success, err := iavlMerkleProofValidateContract.Run(input)
- require.NoError(t, err)
- expectedResult := make([]byte, 32)
- binary.BigEndian.PutUint64(expectedResult[24:], 0x01)
- require.Equal(t, expectedResult, success)
-
- moranValidateContract := iavlMerkleProofValidateMoran{}
- success, err = moranValidateContract.Run(input)
- require.NoError(t, err)
- expectedResult = make([]byte, 32)
- binary.BigEndian.PutUint64(expectedResult[24:], 0x01)
- require.Equal(t, expectedResult, success)
-}
-
-func TestMerkleProofValidateMoran(t *testing.T) {
- // Bytest1 is the inputs of exploit tx 0x05356fd06ce56a9ec5b4eaf9c075abd740cae4c21eab1676440ab5cd2fe5c57a
- bytest1, _ := hex.DecodeString("00000000000000000000000000000000000000000000000000000000000005086962630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000100380200000000010dd9ac0000000000000000000000000000000000000000000000000000000000000093000000000000000000000000000000000000000000000000000000000000000000f870a0424e4200000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000008ad3c21bcecceda100000094489a8756c18c0b8b24ec2a2b9ff3d4d447f79bec94489a8756c18c0b8b24ec2a2b9ff3d4d447f79bec846553f10072cda827a83531ca0fd7ac917a6b65649719aab0836722caafe0603147a523180a8d020a066961766c3a76120e00000100380200000000010dd9ac1af201f0010aed010a2b0802100318b091c73422200c10f902d266c238a4ca9e26fa9bc36483cd3ebee4e263012f5e7f40c22ee4d20a4d0801100218b091c7342220e4fd47bffd1c06e67edad92b2bf9ca63631978676288a2aa99f95c459436ef632a20121a1f9c4eca726c725796c5375fc4158986ced08e498dc8268ef94d8ed1891612001a370a0e0000010038020000000000000002122011056c6919f02d966991c10721684a8d1542e44003f9ffb47032c18995d4ac7f18b091c7341a340a0e00000100380200000000010dd9ac12202c3a561458f8527b002b5ec3cab2d308662798d6245d4588a4e6a80ebdfe30ac18010ad4050a0a6d756c746973746f726512036962631ac005be050abb050a110a066f7261636c6512070a0508b891c7340a0f0a046d61696e12070a0508b891c7340a350a08736c617368696e6712290a2708b891c7341220c8ccf341e6e695e7e1cb0ce4bf347eea0cc16947d8b4e934ec400b57c59d6f860a380a0b61746f6d69635f7377617012290a2708b891c734122042d4ecc9468f71a70288a95d46564bfcaf2c9f811051dcc5593dbef152976b010a110a0662726964676512070a0508b891c7340a300a0364657812290a2708b891c73412201773be443c27f61075cecdc050ce22eb4990c54679089e90afdc4e0e88182a230a2f0a02736312290a2708b891c7341220df7a0484b7244f76861b1642cfb7a61d923794bd2e076c8dbd05fc4ee29f3a670a330a06746f6b656e7312290a2708b891c734122064958c2f76fec1fa5d1828296e51264c259fa264f499724795a740f48fc4731b0a320a057374616b6512290a2708b891c734122015d2c302143bdf029d58fe381cc3b54cedf77ecb8834dfc5dc3e1555d68f19ab0a330a06706172616d7312290a2708b891c734122050abddcb7c115123a5a4247613ab39e6ba935a3d4f4b9123c4fedfa0895c040a0a300a0361636312290a2708b891c734122079fb5aecc4a9b87e56231103affa5e515a1bdf3d0366490a73e087980b7f1f260a0e0a0376616c12070a0508b891c7340a300a0369626312290a2708b891c7341220e09159530585455058cf1785f411ea44230f39334e6e0f6a3c54dbf069df2b620a300a03676f7612290a2708b891c7341220db85ddd37470983b14186e975a175dfb0bf301b43de685ced0aef18d28b4e0420a320a05706169727312290a2708b891c7341220a78b556bc9e73d86b4c63ceaf146db71b12ac80e4c10dd0ce6eb09c99b0c7cfe0a360a0974696d655f6c6f636b12290a2708b891c73412204775dbe01d41cab018c21ba5c2af94720e4d7119baf693670e70a40ba2a52143")
- // Bytest1 is the inputs of exploit tx 0xebf83628ba893d35b496121fb8201666b8e09f3cbadf0e269162baa72efe3b8b
- bytest2, _ := hex.DecodeString("00000000000000000000000000000000000000000000000000000000000005086962630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000100380200000000010dd85c0000000000000000000000000000000000000000000000000000000000000093000000000000000000000000000000000000000000000000000000000000000000f870a0424e4200000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000008ad3c21bcecceda100000094489a8756c18c0b8b24ec2a2b9ff3d4d447f79bec94489a8756c18c0b8b24ec2a2b9ff3d4d447f79bec846553f10072cda827a83531ca0fd7ac917a6b65649719aab0836722caafe0603147a523180a8d020a066961766c3a76120e00000100380200000000010dd85c1af201f0010aed010a2b0802100318b091c73422200c10f902d266c238a4ca9e26fa9bc36483cd3ebee4e263012f5e7f40c22ee4d20a4d0801100218b091c7342220e4fd47bffd1c06e67edad92b2bf9ca63631978676288a2aa99f95c459436ef632a20da657c1ffb86c684eb3e265361ef0fa4f9dfa670b45f9f91c5eb6ad84b21a4d112001a370a0e0000010038020000000000000002122011056c6919f02d966991c10721684a8d1542e44003f9ffb47032c18995d4ac7f18b091c7341a340a0e00000100380200000000010dd85c12202c3a561458f8527b002b5ec3cab2d308662798d6245d4588a4e6a80ebdfe30ac18010ad4050a0a6d756c746973746f726512036962631ac005be050abb050a110a066f7261636c6512070a0508b891c7340a0f0a046d61696e12070a0508b891c7340a350a08736c617368696e6712290a2708b891c7341220c8ccf341e6e695e7e1cb0ce4bf347eea0cc16947d8b4e934ec400b57c59d6f860a380a0b61746f6d69635f7377617012290a2708b891c734122042d4ecc9468f71a70288a95d46564bfcaf2c9f811051dcc5593dbef152976b010a110a0662726964676512070a0508b891c7340a300a0364657812290a2708b891c73412201773be443c27f61075cecdc050ce22eb4990c54679089e90afdc4e0e88182a230a2f0a02736312290a2708b891c7341220df7a0484b7244f76861b1642cfb7a61d923794bd2e076c8dbd05fc4ee29f3a670a330a06746f6b656e7312290a2708b891c734122064958c2f76fec1fa5d1828296e51264c259fa264f499724795a740f48fc4731b0a320a057374616b6512290a2708b891c734122015d2c302143bdf029d58fe381cc3b54cedf77ecb8834dfc5dc3e1555d68f19ab0a330a06706172616d7312290a2708b891c734122050abddcb7c115123a5a4247613ab39e6ba935a3d4f4b9123c4fedfa0895c040a0a300a0361636312290a2708b891c734122079fb5aecc4a9b87e56231103affa5e515a1bdf3d0366490a73e087980b7f1f260a0e0a0376616c12070a0508b891c7340a300a0369626312290a2708b891c7341220e09159530585455058cf1785f411ea44230f39334e6e0f6a3c54dbf069df2b620a300a03676f7612290a2708b891c7341220db85ddd37470983b14186e975a175dfb0bf301b43de685ced0aef18d28b4e0420a320a05706169727312290a2708b891c7341220a78b556bc9e73d86b4c63ceaf146db71b12ac80e4c10dd0ce6eb09c99b0c7cfe0a360a0974696d655f6c6f636b12290a2708b891c73412204775dbe01d41cab018c21ba5c2af94720e4d7119baf693670e70a40ba2a52143")
-
- for _, bytest := range [][]byte{bytest1, bytest2} {
- validator := iavlMerkleProofValidate{}
- res, err := validator.Run(bytest)
- assert.NoError(t, err)
- assert.Equal(t, res[len(res)-1], uint8(1))
-
- moranValidator := iavlMerkleProofValidateMoran{}
- res, err = moranValidator.Run(bytest)
- assert.Errorf(t, err, "invalid merkle proof")
- assert.Nil(t, res)
- }
-}
-
-func TestAbsenceMerkleProofValidateMoran(t *testing.T) {
- // Bytest contains absence op
- bytest, _ := hex.DecodeString("00000000000000000000000000000000000000000000000000000000000007306163630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c6163636f756e743a8a4e2eb018bdf98a8f53ec755740ffc728637a1d000000000000000000000000000000000000000000000000000000000000007b4bdc4c270a750a148a4e2eb018bdf98a8f53ec755740ffc728637a1d12110a0941544348412d3733301080f69bf321120b0a03424e4210e8baeb8d44120f0a075050432d303041108094ebdc031a26eb5ae98721031c199c92e5b0080967da99be27cf2da53317441b4a663e6d9c6caf02be1fdbdc20d7962b28152c69c314b4de5c8035253c8bc0771d9ca17b1b23a57c0c6d068b57579791cae20add070a066961766c3a61121c6163636f756e743a8a4e2eb018bdf98a8f53ec755740ffc728637a1d1ab407b2070aaf070a2d081810cdfd2b188096a82222209f223f804e2d94ac51c4321b0687397012e6d95eb9783b03bc790da631004c7c0a2d081710adb31a18f395a8222a20d2a38865de82383ccce0140513b65cec1bf2ae6cd7dfeb22eb6faadb4e26b26f0a2d081510b2990b18f395a82222208a02bbd5a695dfc772627ac8744aa9cf30ae26575bdce8c96a9a0d0999175b430a2d081410e6ff0418f395a8222a20d39619c779be909e67f23499fb74eb2c19afd7f21523401d4ccf7e917db5cd600a2d081210e3fe0118f395a8222a20a10cc73843f889d9e03a463eb135e928bb980e19734344cba0fbf4e8a4c5258b0a2c081010dd6518f395a8222a2007fd15843a2fd3f58d021b0e072a6c70742d7a3d993a922445e3491e1c14ee8e0a2c080f10cc2a18eda6a7222a20088942d7b30abd021d8e9505cc41313fad87c8c10a799f3b51018b7b2cfe4ad90a2c080d10b70d18eda6a7222a2091a37bc44d0c61e3752ddc59eb390355ab65e8a9fb453be4f0acec537f1ca14f0a2c080c10890818eda6a72222201cfc317855a06667c45812fe36efe33af05671dfe0d9b56b02662011af2e79e30a2c080b10ac0318c4b0ee212220aeb454a4b3243b6269a2fd8841dca9a951c53b30f1e27da91063dae7224402c70a2c080910e40118c4b0ee212a20441340a4de6498f861b97b3f3ad9603af055e5af51a0d96fff2ae28e3c5c6c9a0a2c0808108d0118c4b0ee212220ae32ea4b9ab7b53571da320e2815fd8b2c278124961cca4a1849a799842424450a2b0807104d18c4b0ee212220e2804c9b7f045ec0b4ab20920a937b82fda8b7a9ddd12b21637335b915cfda550a2b0806102418a5f4c7192a20ec85f22addedfc82c771af5b4c77544b7c1d7c5bbac33f2712dfba1045ebdbd00a2b0805101118a5f4c7192a2071ade34dcc447a0ba8adc603080633d15c06f3525830c86ebce35eca0a4921fc0a2b0804100c18a5f4c7192a205190bce93993e65b266a3417ed511df8897a812cb4b62569e5afcfbec10b69cd0a2b0803100618a5f4c7192220b76c6884f1d412ac10bfb3987fb7d26f0330b2a85539509ebc5c6bdec2f95d520a2b0802100418a5f4c71922206a285b4a4f9d1c687bbafa1f3649b6a6e32b1a85dd0402421210683e846cf0020a2b0801100218a5f4c7192220033b3f7c6dcb258b6e55545e7a4f51539447cd595eb8a2e373ba0015502da1051a450a1c6163636f756e743a8a4e2eb018bdf98a8f53ec755740ffc728637a1d12201a272295e94cf1d8090bdb019dde48e9dab026ad2c3e43aaa7e61cc954a9245d18a5f4c7190ab6040a0a6d756c746973746f726512036163631aa204a0040a9d040a300a0364657812290a27088496a822122038fc49f49648fec62acc434151a51eaa378c1b20a730a749548e36f1529422500a300a03676f7612290a27088496a8221220a78ce489bdf08b9ee869c184876e1623dc38b3e64a5cf1a0005f97976c64deac0a380a0b61746f6d69635f7377617012290a27088496a8221220544c2fa38f61e10a39ec00b3e724d5834761268bb455cdbf5843bcf1531f8fbc0a300a0376616c12290a27088496a82212201f71082c9f6f45fb456b2c00b41e50d2f662f2dfec3cb6965f19d214bf02f3980a0f0a046d61696e12070a05088496a8220a320a057374616b6512290a27088496a82212200dd467343c718f240e50b4feac42970fc8c1c69a018be955f9c27913ac1f8b3c0a300a0361636312290a27088496a8221220270c19ccc9c40c5176b3dfbd8af734c97a307e0dbd8df9e286dcd5d709f973ed0a330a06746f6b656e7312290a27088496a8221220c4f96eedf50c83964de9df013afec2e545012d92528b643a5166c828774187b60a320a05706169727312290a27088496a8221220351c55cfda84596ecd22ebc77013662aba97f81f19d9ef3d150213bb07c823060a360a0974696d655f6c6f636b12290a27088496a8221220e7adf5bd30ce022decf0e9341bf05c464ed70cdbc97423bd2bab8f3571e5179b0a330a06706172616d7312290a27088496a822122042a9dfc356ca435db131eb41fb1975c8482f2434537918665e530b0b4633b5f9")
- moranValidator := iavlMerkleProofValidateMoran{}
- res, err := moranValidator.Run(bytest)
- assert.Errorf(t, err, "invalid merkle proof")
- assert.Nil(t, res)
-}
-
-func TestMultiStore(t *testing.T) {
- goodProof := lightclient.NewMultiStoreProofOp([]byte("legit"), &lightclient.MultiStoreProof{
- StoreInfos: []lightclient.StoreInfo{
- {
- Name: "legit",
- Core: lightclient.StoreCore{
- CommitID: lightclient.CommitID{
- Version: 1,
- Hash: []byte("legithash"),
- },
- },
- },
- },
- })
-
- result1, err := goodProof.Run([][]byte{[]byte("legithash")})
- assert.NoError(t, err)
-
- _, err = goodProof.Run([][]byte{[]byte("evilhash")})
- assert.Error(t, err, "hash mismatch for substore")
-
- badProof := lightclient.NewMultiStoreProofOp([]byte("legit"), &lightclient.MultiStoreProof{
- StoreInfos: []lightclient.StoreInfo{
- {
- Name: "legit",
- Core: lightclient.StoreCore{
- CommitID: lightclient.CommitID{
- Version: 1,
- Hash: []byte("evilhash"),
- },
- },
- },
- {
- Name: "legit",
- Core: lightclient.StoreCore{
- CommitID: lightclient.CommitID{
- Version: 1,
- Hash: []byte("legithash"),
- },
- },
- },
- },
- })
-
- _, err = badProof.Run([][]byte{[]byte("legithash")})
- assert.Error(t, err, "hash mismatch for substore")
-
- result2, err := badProof.Run([][]byte{[]byte("evilhash")})
- assert.NoError(t, err)
- assert.Equal(t, result1, result2)
-
- err = multiStoreOpVerifier(badProof)
- assert.Error(t, err, "duplicated store")
-}
diff --git a/core/vm/evm.go b/core/vm/evm.go
index c7ae784ff..632ee1d0d 100644
--- a/core/vm/evm.go
+++ b/core/vm/evm.go
@@ -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:
diff --git a/eth/backend.go b/eth/backend.go
index 54980719a..d205db455 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -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
diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go
index 2fb179976..4bbbc670e 100644
--- a/eth/ethconfig/config.go
+++ b/eth/ethconfig/config.go
@@ -206,7 +206,6 @@ type Config struct {
Clique params.ConsensusSnapshotConfig
Aura chain.AuRaConfig
- Parlia chain.ParliaConfig
Bor chain.BorConfig
// Transaction pool options
diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go
index 05e2faf4a..ff557ae08 100644
--- a/eth/ethconfig/gen_config.go
+++ b/eth/ethconfig/gen_config.go
@@ -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
}
diff --git a/eth/ethconsensusconfig/config.go b/eth/ethconsensusconfig/config.go
index fe3123a87..02bb9f395 100644
--- a/eth/ethconsensusconfig/config.go
+++ b/eth/ethconsensusconfig/config.go
@@ -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
diff --git a/eth/stagedsync/exec3.go b/eth/stagedsync/exec3.go
index 7a1a1e957..baf0eeacb 100644
--- a/eth/stagedsync/exec3.go
+++ b/eth/stagedsync/exec3.go
@@ -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
diff --git a/eth/stagedsync/stage_execute.go b/eth/stagedsync/stage_execute.go
index 2eca369fd..869d49727 100644
--- a/eth/stagedsync/stage_execute.go
+++ b/eth/stagedsync/stage_execute.go
@@ -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)
diff --git a/eth/stagedsync/stage_headers.go b/eth/stagedsync/stage_headers.go
index 2275ec616..a57cb9ccb 100644
--- a/eth/stagedsync/stage_headers.go
+++ b/eth/stagedsync/stage_headers.go
@@ -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 {
diff --git a/eth/stagedsync/stage_mining_exec.go b/eth/stagedsync/stage_mining_exec.go
index 76c001dbd..dadf96783 100644
--- a/eth/stagedsync/stage_mining_exec.go
+++ b/eth/stagedsync/stage_mining_exec.go
@@ -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
diff --git a/eth/stagedsync/stage_snapshots.go b/eth/stagedsync/stage_snapshots.go
index 211784480..1ce54740c 100644
--- a/eth/stagedsync/stage_snapshots.go
+++ b/eth/stagedsync/stage_snapshots.go
@@ -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()
diff --git a/go.mod b/go.mod
index 551602965..3adeff1d3 100644
--- a/go.mod
+++ b/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
diff --git a/go.sum b/go.sum
index 6ab9c6d88..b111c0117 100644
--- a/go.sum
+++ b/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=
diff --git a/params/protocol_params.go b/params/protocol_params.go
index b34caab01..e4cc0669c 100644
--- a/params/protocol_params.go
+++ b/params/protocol_params.go
@@ -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
-}