mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 03:30:37 +00:00
Add support for PulseChain
Thanks @bretep for the original integration.
This commit is contained in:
parent
aa3a804757
commit
75db06fa1d
21
Dockerfile
21
Dockerfile
@ -42,17 +42,6 @@ FROM docker.io/library/alpine:3.17
|
|||||||
RUN apk add --no-cache ca-certificates libstdc++ tzdata
|
RUN apk add --no-cache ca-certificates libstdc++ tzdata
|
||||||
RUN apk add --no-cache curl jq bind-tools
|
RUN apk add --no-cache curl jq bind-tools
|
||||||
|
|
||||||
# Setup user and group
|
|
||||||
#
|
|
||||||
# from the perspective of the container, uid=1000, gid=1000 is a sensible choice
|
|
||||||
# (mimicking Ubuntu Server), but if caller creates a .env (example in repo root),
|
|
||||||
# these defaults will get overridden when make calls docker-compose
|
|
||||||
ARG UID=1000
|
|
||||||
ARG GID=1000
|
|
||||||
RUN adduser -D -u $UID -g $GID erigon
|
|
||||||
USER erigon
|
|
||||||
RUN mkdir -p ~/.local/share/erigon
|
|
||||||
|
|
||||||
# copy compiled artifacts from builder
|
# copy compiled artifacts from builder
|
||||||
## first do the mdbx ones - since these wont change as often
|
## first do the mdbx ones - since these wont change as often
|
||||||
COPY --from=tools-builder /app/build/bin/mdbx_chk /usr/local/bin/mdbx_chk
|
COPY --from=tools-builder /app/build/bin/mdbx_chk /usr/local/bin/mdbx_chk
|
||||||
@ -98,13 +87,13 @@ ARG BUILD_DATE
|
|||||||
ARG VCS_REF
|
ARG VCS_REF
|
||||||
ARG VERSION
|
ARG VERSION
|
||||||
LABEL org.label-schema.build-date=$BUILD_DATE \
|
LABEL org.label-schema.build-date=$BUILD_DATE \
|
||||||
org.label-schema.description="Erigon Ethereum Client" \
|
org.label-schema.description="Erigon Ethereum Client with PulseChain" \
|
||||||
org.label-schema.name="Erigon" \
|
org.label-schema.name="Erigon PulseChain" \
|
||||||
org.label-schema.schema-version="1.0" \
|
org.label-schema.schema-version="1.0" \
|
||||||
org.label-schema.url="https://torquem.ch" \
|
org.label-schema.url="https://gitlab.com/pulsechaincom/erigon-pulse" \
|
||||||
org.label-schema.vcs-ref=$VCS_REF \
|
org.label-schema.vcs-ref=$VCS_REF \
|
||||||
org.label-schema.vcs-url="https://github.com/ledgerwatch/erigon.git" \
|
org.label-schema.vcs-url="https://gitlab.com/pulsechaincom/erigon-pulse.git" \
|
||||||
org.label-schema.vendor="Torquem" \
|
org.label-schema.vendor="PulseChain" \
|
||||||
org.label-schema.version=$VERSION
|
org.label-schema.version=$VERSION
|
||||||
|
|
||||||
ENTRYPOINT ["erigon"]
|
ENTRYPOINT ["erigon"]
|
||||||
|
1
Makefile
1
Makefile
@ -79,6 +79,7 @@ docker: validate_docker_build_args git-submodules
|
|||||||
--build-arg VERSION=${GIT_TAG} \
|
--build-arg VERSION=${GIT_TAG} \
|
||||||
--build-arg UID=${DOCKER_UID} \
|
--build-arg UID=${DOCKER_UID} \
|
||||||
--build-arg GID=${DOCKER_GID} \
|
--build-arg GID=${DOCKER_GID} \
|
||||||
|
--build-arg DEPLOY_TOKEN=${DEPLOY_TOKEN} \
|
||||||
${DOCKER_FLAGS} \
|
${DOCKER_FLAGS} \
|
||||||
.
|
.
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ var (
|
|||||||
maxPendPeers int
|
maxPendPeers int
|
||||||
healthCheck bool
|
healthCheck bool
|
||||||
metrics bool
|
metrics bool
|
||||||
|
chainName string
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -55,6 +56,7 @@ func init() {
|
|||||||
rootCmd.Flags().IntVar(&maxPendPeers, utils.MaxPendingPeersFlag.Name, utils.MaxPendingPeersFlag.Value, utils.MaxPendingPeersFlag.Usage)
|
rootCmd.Flags().IntVar(&maxPendPeers, utils.MaxPendingPeersFlag.Name, utils.MaxPendingPeersFlag.Value, utils.MaxPendingPeersFlag.Usage)
|
||||||
rootCmd.Flags().BoolVar(&healthCheck, utils.HealthCheckFlag.Name, false, utils.HealthCheckFlag.Usage)
|
rootCmd.Flags().BoolVar(&healthCheck, utils.HealthCheckFlag.Name, false, utils.HealthCheckFlag.Usage)
|
||||||
rootCmd.Flags().BoolVar(&metrics, utils.MetricsEnabledFlag.Name, false, utils.MetricsEnabledFlag.Usage)
|
rootCmd.Flags().BoolVar(&metrics, utils.MetricsEnabledFlag.Name, false, utils.MetricsEnabledFlag.Usage)
|
||||||
|
rootCmd.Flags().StringVar(&chainName, utils.ChainFlag.Name, utils.ChainFlag.Value, utils.ChainFlag.Usage)
|
||||||
|
|
||||||
if err := rootCmd.MarkFlagDirname(utils.DataDirFlag.Name); err != nil {
|
if err := rootCmd.MarkFlagDirname(utils.DataDirFlag.Name); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -88,6 +90,7 @@ var rootCmd = &cobra.Command{
|
|||||||
protocol,
|
protocol,
|
||||||
allowedPorts,
|
allowedPorts,
|
||||||
metrics,
|
metrics,
|
||||||
|
chainName,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -97,7 +97,7 @@ var (
|
|||||||
}
|
}
|
||||||
ChainFlag = cli.StringFlag{
|
ChainFlag = cli.StringFlag{
|
||||||
Name: "chain",
|
Name: "chain",
|
||||||
Usage: "name of the network to join",
|
Usage: "Name of the network to join",
|
||||||
Value: networkname.MainnetChainName,
|
Value: networkname.MainnetChainName,
|
||||||
}
|
}
|
||||||
IdentityFlag = cli.StringFlag{
|
IdentityFlag = cli.StringFlag{
|
||||||
@ -1062,6 +1062,7 @@ func NewP2PConfig(
|
|||||||
protocol uint,
|
protocol uint,
|
||||||
allowedPorts []uint,
|
allowedPorts []uint,
|
||||||
metricsEnabled bool,
|
metricsEnabled bool,
|
||||||
|
chainName string,
|
||||||
) (*p2p.Config, error) {
|
) (*p2p.Config, error) {
|
||||||
var enodeDBPath string
|
var enodeDBPath string
|
||||||
switch protocol {
|
switch protocol {
|
||||||
@ -1092,6 +1093,7 @@ func NewP2PConfig(
|
|||||||
AllowedPorts: allowedPorts,
|
AllowedPorts: allowedPorts,
|
||||||
TmpDir: dirs.Tmp,
|
TmpDir: dirs.Tmp,
|
||||||
MetricsEnabled: metricsEnabled,
|
MetricsEnabled: metricsEnabled,
|
||||||
|
ChainName: chainName,
|
||||||
}
|
}
|
||||||
if netRestrict != "" {
|
if netRestrict != "" {
|
||||||
cfg.NetRestrict = new(netutil.Netlist)
|
cfg.NetRestrict = new(netutil.Netlist)
|
||||||
@ -1771,7 +1773,7 @@ func SetDNSDiscoveryDefaults(cfg *ethconfig.Config, genesis libcommon.Hash) {
|
|||||||
return // already set through flags/config
|
return // already set through flags/config
|
||||||
}
|
}
|
||||||
protocol := "all"
|
protocol := "all"
|
||||||
if url := params.KnownDNSNetwork(genesis, protocol); url != "" {
|
if url := params.KnownDNSNetwork(genesis, cfg.NetworkID, protocol); url != "" {
|
||||||
cfg.EthDiscoveryURLs = []string{url}
|
cfg.EthDiscoveryURLs = []string{url}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,6 +100,10 @@ func DataDirForNetwork(datadir string, network string) string {
|
|||||||
return networkDataDirCheckingLegacy(datadir, "gnosis")
|
return networkDataDirCheckingLegacy(datadir, "gnosis")
|
||||||
case networkname.ChiadoChainName:
|
case networkname.ChiadoChainName:
|
||||||
return networkDataDirCheckingLegacy(datadir, "chiado")
|
return networkDataDirCheckingLegacy(datadir, "chiado")
|
||||||
|
case networkname.PulsechainChainName:
|
||||||
|
return networkDataDirCheckingLegacy(datadir, "pulsechain")
|
||||||
|
case networkname.PulsechainTestnetChainName:
|
||||||
|
return networkDataDirCheckingLegacy(datadir, "pulsechain-testnet")
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return datadir
|
return datadir
|
||||||
|
@ -39,6 +39,7 @@ import (
|
|||||||
"github.com/ledgerwatch/erigon/core/state"
|
"github.com/ledgerwatch/erigon/core/state"
|
||||||
"github.com/ledgerwatch/erigon/core/types"
|
"github.com/ledgerwatch/erigon/core/types"
|
||||||
"github.com/ledgerwatch/erigon/params"
|
"github.com/ledgerwatch/erigon/params"
|
||||||
|
"github.com/ledgerwatch/erigon/pulse"
|
||||||
"github.com/ledgerwatch/erigon/rlp"
|
"github.com/ledgerwatch/erigon/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -294,6 +295,8 @@ func (ethash *Ethash) CalcDifficulty(chain consensus.ChainHeaderReader, time, pa
|
|||||||
func CalcDifficulty(config *chain.Config, time, parentTime uint64, parentDifficulty *big.Int, parentNumber uint64, parentUncleHash libcommon.Hash) *big.Int {
|
func CalcDifficulty(config *chain.Config, time, parentTime uint64, parentDifficulty *big.Int, parentNumber uint64, parentUncleHash libcommon.Hash) *big.Int {
|
||||||
next := parentNumber + 1
|
next := parentNumber + 1
|
||||||
switch {
|
switch {
|
||||||
|
case config.IsPrimordialPulseBlock(next):
|
||||||
|
return chain.PulseChainTTDOffset
|
||||||
case config.IsGrayGlacier(next):
|
case config.IsGrayGlacier(next):
|
||||||
return calcDifficultyEip5133(time, parentTime, parentDifficulty, parentNumber, parentUncleHash)
|
return calcDifficultyEip5133(time, parentTime, parentDifficulty, parentNumber, parentUncleHash)
|
||||||
case config.IsArrowGlacier(next):
|
case config.IsArrowGlacier(next):
|
||||||
@ -562,6 +565,11 @@ func (ethash *Ethash) Finalize(config *chain.Config, header *types.Header, state
|
|||||||
txs types.Transactions, uncles []*types.Header, r types.Receipts, withdrawals []*types.Withdrawal,
|
txs types.Transactions, uncles []*types.Header, r types.Receipts, withdrawals []*types.Withdrawal,
|
||||||
chain consensus.ChainReader, syscall consensus.SystemCall, logger log.Logger,
|
chain consensus.ChainReader, syscall consensus.SystemCall, logger log.Logger,
|
||||||
) (types.Transactions, types.Receipts, error) {
|
) (types.Transactions, types.Receipts, error) {
|
||||||
|
// Apply fork changes on PrimordialPulse block
|
||||||
|
if cfg := chain.Config(); cfg.IsPrimordialPulseBlock(header.Number.Uint64()) {
|
||||||
|
pulse.PrimordialPulseFork(state, cfg.PulseChain)
|
||||||
|
}
|
||||||
|
|
||||||
// Accumulate any block and uncle rewards and commit the final state root
|
// Accumulate any block and uncle rewards and commit the final state root
|
||||||
accumulateRewards(config, state, header, uncles)
|
accumulateRewards(config, state, header, uncles)
|
||||||
return txs, r, nil
|
return txs, r, nil
|
||||||
|
@ -82,8 +82,8 @@ func (s *Merge) VerifyHeader(chain consensus.ChainHeaderReader, header *types.He
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !reached {
|
if !reached && (chain.Config().PulseChain == nil || !misc.IsPoSHeader(header)) {
|
||||||
// Not verifying seals if the TTD is passed
|
// Delegate non-PoS block to eth1 verification
|
||||||
return s.eth1Engine.VerifyHeader(chain, header, !chain.Config().TerminalTotalDifficultyPassed)
|
return s.eth1Engine.VerifyHeader(chain, header, !chain.Config().TerminalTotalDifficultyPassed)
|
||||||
}
|
}
|
||||||
// Short circuit if the parent is not known
|
// Short circuit if the parent is not known
|
||||||
|
@ -121,12 +121,18 @@ func WriteGenesisBlock(tx kv.RwTx, genesis *types.Genesis, overrideCancunTime *b
|
|||||||
return genesis.Config, block, nil
|
return genesis.Config, block, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Assume mainnet chainId first
|
||||||
|
chainId := params.MainnetChainConfig.ChainID.Uint64()
|
||||||
|
|
||||||
// Check whether the genesis block is already written.
|
// Check whether the genesis block is already written.
|
||||||
if genesis != nil {
|
if genesis != nil {
|
||||||
block, _, err1 := GenesisToBlock(genesis, tmpDir, logger)
|
block, _, err1 := GenesisToBlock(genesis, tmpDir, logger)
|
||||||
if err1 != nil {
|
if err1 != nil {
|
||||||
return genesis.Config, nil, err1
|
return genesis.Config, nil, err1
|
||||||
}
|
}
|
||||||
|
// Use the incoming chainID for building chain config.
|
||||||
|
// Allows for mainnet genesis w/ pulsechain config.
|
||||||
|
chainId = genesis.Config.ChainID.Uint64()
|
||||||
hash := block.Hash()
|
hash := block.Hash()
|
||||||
if hash != storedHash {
|
if hash != storedHash {
|
||||||
return genesis.Config, block, &types.GenesisMismatchError{Stored: storedHash, New: hash}
|
return genesis.Config, block, &types.GenesisMismatchError{Stored: storedHash, New: hash}
|
||||||
@ -140,13 +146,18 @@ func WriteGenesisBlock(tx kv.RwTx, genesis *types.Genesis, overrideCancunTime *b
|
|||||||
return genesis.Config, nil, err
|
return genesis.Config, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
storedCfg, storedErr := rawdb.ReadChainConfig(tx, storedHash)
|
||||||
|
if storedErr == nil && storedCfg != nil {
|
||||||
|
// Use the existing chainID for building chain config.
|
||||||
|
// Allows for mainnet genesis w/ pulsechain config.
|
||||||
|
chainId = storedCfg.ChainID.Uint64()
|
||||||
|
}
|
||||||
// Get the existing chain configuration.
|
// Get the existing chain configuration.
|
||||||
newCfg := genesis.ConfigOrDefault(storedHash)
|
newCfg := genesis.ConfigOrDefault(storedHash, chainId)
|
||||||
applyOverrides(newCfg)
|
applyOverrides(newCfg)
|
||||||
if err := newCfg.CheckConfigForkOrder(); err != nil {
|
if err := newCfg.CheckConfigForkOrder(); err != nil {
|
||||||
return newCfg, nil, err
|
return newCfg, nil, err
|
||||||
}
|
}
|
||||||
storedCfg, storedErr := rawdb.ReadChainConfig(tx, storedHash)
|
|
||||||
if storedErr != nil && newCfg.Bor == nil {
|
if storedErr != nil && newCfg.Bor == nil {
|
||||||
return newCfg, nil, storedErr
|
return newCfg, nil, storedErr
|
||||||
}
|
}
|
||||||
@ -457,6 +468,28 @@ func ChiadoGenesisBlock() *types.Genesis {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func PulsechainGenesisBlock() *types.Genesis {
|
||||||
|
return &types.Genesis{
|
||||||
|
Config: params.PulsechainChainConfig,
|
||||||
|
Nonce: 66,
|
||||||
|
ExtraData: hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"),
|
||||||
|
GasLimit: 5000,
|
||||||
|
Difficulty: big.NewInt(17179869184),
|
||||||
|
Alloc: readPrealloc("allocs/mainnet.json"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func PulsechainTestnetGenesisBlock() *types.Genesis {
|
||||||
|
return &types.Genesis{
|
||||||
|
Config: params.PulsechainTestnetChainConfig,
|
||||||
|
Nonce: 66,
|
||||||
|
ExtraData: hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"),
|
||||||
|
GasLimit: 5000,
|
||||||
|
Difficulty: big.NewInt(17179869184),
|
||||||
|
Alloc: readPrealloc("allocs/mainnet.json"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Pre-calculated version of:
|
// Pre-calculated version of:
|
||||||
//
|
//
|
||||||
// DevnetSignPrivateKey = crypto.HexToECDSA(sha256.Sum256([]byte("erigon devnet key")))
|
// DevnetSignPrivateKey = crypto.HexToECDSA(sha256.Sum256([]byte("erigon devnet key")))
|
||||||
@ -675,6 +708,10 @@ func GenesisBlockByChainName(chain string) *types.Genesis {
|
|||||||
return GnosisGenesisBlock()
|
return GnosisGenesisBlock()
|
||||||
case networkname.ChiadoChainName:
|
case networkname.ChiadoChainName:
|
||||||
return ChiadoGenesisBlock()
|
return ChiadoGenesisBlock()
|
||||||
|
case networkname.PulsechainChainName:
|
||||||
|
return PulsechainGenesisBlock()
|
||||||
|
case networkname.PulsechainTestnetChainName:
|
||||||
|
return PulsechainTestnetGenesisBlock()
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,8 @@ import (
|
|||||||
var analysisBlocks = map[string][]uint64{
|
var analysisBlocks = map[string][]uint64{
|
||||||
networkname.MainnetChainName: {5_800_596, 6_426_298, 6_426_432, 11_079_912, 13_119_520, 15_081_051},
|
networkname.MainnetChainName: {5_800_596, 6_426_298, 6_426_432, 11_079_912, 13_119_520, 15_081_051},
|
||||||
networkname.BorMainnetChainName: {29_447_463},
|
networkname.BorMainnetChainName: {29_447_463},
|
||||||
|
networkname.PulsechainChainName: {5_800_596, 6_426_298, 6_426_432, 11_079_912, 13_119_520, 15_081_051},
|
||||||
|
networkname.PulsechainTestnetChainName: {5_800_596, 6_426_298, 6_426_432, 11_079_912, 13_119_520, 15_081_051},
|
||||||
}
|
}
|
||||||
|
|
||||||
func SkipAnalysis(config *chain.Config, blockNumber uint64) bool {
|
func SkipAnalysis(config *chain.Config, blockNumber uint64) bool {
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ledgerwatch/erigon-lib/chain"
|
"github.com/ledgerwatch/erigon-lib/chain"
|
||||||
|
"github.com/ledgerwatch/erigon-lib/chain/networkname"
|
||||||
"github.com/ledgerwatch/erigon-lib/common"
|
"github.com/ledgerwatch/erigon-lib/common"
|
||||||
"github.com/ledgerwatch/erigon-lib/common/hexutility"
|
"github.com/ledgerwatch/erigon-lib/common/hexutility"
|
||||||
|
|
||||||
@ -165,12 +166,23 @@ func (e *GenesisMismatchError) Error() string {
|
|||||||
}
|
}
|
||||||
return fmt.Sprintf("database contains incompatible genesis (try with --chain=%s)", config.ChainName)
|
return fmt.Sprintf("database contains incompatible genesis (try with --chain=%s)", config.ChainName)
|
||||||
}
|
}
|
||||||
func (g *Genesis) ConfigOrDefault(genesisHash common.Hash) *chain.Config {
|
func (g *Genesis) ConfigOrDefault(genesisHash common.Hash, chainId uint64) *chain.Config {
|
||||||
if g != nil {
|
if g != nil {
|
||||||
return g.Config
|
return g.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
config := params.ChainConfigByGenesisHash(genesisHash)
|
var config *chain.Config
|
||||||
|
pulseChainConfig := params.ChainConfigByChainName(networkname.PulsechainChainName)
|
||||||
|
pulseChainTestnetConfig := params.ChainConfigByChainName(networkname.PulsechainTestnetChainName)
|
||||||
|
switch chainId {
|
||||||
|
case pulseChainConfig.ChainID.Uint64():
|
||||||
|
config = pulseChainConfig
|
||||||
|
case pulseChainTestnetConfig.ChainID.Uint64():
|
||||||
|
config = pulseChainTestnetConfig
|
||||||
|
default:
|
||||||
|
config = params.ChainConfigByGenesisHash(genesisHash)
|
||||||
|
}
|
||||||
|
|
||||||
if config != nil {
|
if config != nil {
|
||||||
return config
|
return config
|
||||||
} else {
|
} else {
|
||||||
|
@ -42,6 +42,12 @@ func MakeSigner(config *chain.Config, blockNumber uint64, blockTime uint64) *Sig
|
|||||||
if overflow {
|
if overflow {
|
||||||
panic(fmt.Errorf("chainID higher than 2^256-1"))
|
panic(fmt.Errorf("chainID higher than 2^256-1"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.PrimordialPulseAhead(blockNumber) {
|
||||||
|
// ethereum mainnet chainID is 1
|
||||||
|
// required to validate transactions on mainnet
|
||||||
|
chainId.SetOne()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
signer.unprotected = true
|
signer.unprotected = true
|
||||||
switch {
|
switch {
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package vm
|
package vm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/big"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/holiman/uint256"
|
"github.com/holiman/uint256"
|
||||||
@ -97,13 +98,24 @@ type EVM struct {
|
|||||||
// NewEVM returns a new EVM. The returned EVM is not thread safe and should
|
// NewEVM returns a new EVM. The returned EVM is not thread safe and should
|
||||||
// only ever be used *once*.
|
// only ever be used *once*.
|
||||||
func NewEVM(blockCtx evmtypes.BlockContext, txCtx evmtypes.TxContext, state evmtypes.IntraBlockState, chainConfig *chain.Config, vmConfig Config) *EVM {
|
func NewEVM(blockCtx evmtypes.BlockContext, txCtx evmtypes.TxContext, state evmtypes.IntraBlockState, chainConfig *chain.Config, vmConfig Config) *EVM {
|
||||||
|
flexChainConfig := chainConfig
|
||||||
|
|
||||||
|
if flexChainConfig.PrimordialPulseAhead(blockCtx.BlockNumber) {
|
||||||
|
// create a shallow of chainConfig struct and set to ethereum mainnet
|
||||||
|
chainCfgCpy := *chainConfig
|
||||||
|
chainCfgCpy.ChainID = big.NewInt(1)
|
||||||
|
|
||||||
|
// use the new chainCfgCpy
|
||||||
|
flexChainConfig = &chainCfgCpy
|
||||||
|
}
|
||||||
|
|
||||||
evm := &EVM{
|
evm := &EVM{
|
||||||
Context: blockCtx,
|
Context: blockCtx,
|
||||||
TxContext: txCtx,
|
TxContext: txCtx,
|
||||||
intraBlockState: state,
|
intraBlockState: state,
|
||||||
config: vmConfig,
|
config: vmConfig,
|
||||||
chainConfig: chainConfig,
|
chainConfig: flexChainConfig,
|
||||||
chainRules: chainConfig.Rules(blockCtx.BlockNumber, blockCtx.Time),
|
chainRules: flexChainConfig.Rules(blockCtx.BlockNumber, blockCtx.Time),
|
||||||
}
|
}
|
||||||
|
|
||||||
evm.interpreter = NewEVMInterpreter(evm, vmConfig)
|
evm.interpreter = NewEVMInterpreter(evm, vmConfig)
|
||||||
|
@ -68,6 +68,9 @@ type Config struct {
|
|||||||
CancunTime *big.Int `json:"cancunTime,omitempty"`
|
CancunTime *big.Int `json:"cancunTime,omitempty"`
|
||||||
PragueTime *big.Int `json:"pragueTime,omitempty"`
|
PragueTime *big.Int `json:"pragueTime,omitempty"`
|
||||||
|
|
||||||
|
// PulseChain fork blocks
|
||||||
|
PrimordialPulseBlock *big.Int `json:"primordialPulseBlock,omitempty"` // PrimordialPulseBlock switch block (nil = no fork, 0 = already activated)
|
||||||
|
|
||||||
// Optional EIP-4844 parameters
|
// Optional EIP-4844 parameters
|
||||||
MinBlobGasPrice *uint64 `json:"minBlobGasPrice,omitempty"`
|
MinBlobGasPrice *uint64 `json:"minBlobGasPrice,omitempty"`
|
||||||
MaxBlobGasPerBlock *uint64 `json:"maxBlobGasPerBlock,omitempty"`
|
MaxBlobGasPerBlock *uint64 `json:"maxBlobGasPerBlock,omitempty"`
|
||||||
@ -84,6 +87,8 @@ type Config struct {
|
|||||||
|
|
||||||
Bor BorConfig `json:"-"`
|
Bor BorConfig `json:"-"`
|
||||||
BorJSON json.RawMessage `json:"bor,omitempty"`
|
BorJSON json.RawMessage `json:"bor,omitempty"`
|
||||||
|
|
||||||
|
PulseChain *PulseChainConfig `json:"pulseChain,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type BorConfig interface {
|
type BorConfig interface {
|
||||||
@ -97,7 +102,7 @@ type BorConfig interface {
|
|||||||
func (c *Config) String() string {
|
func (c *Config) String() string {
|
||||||
engine := c.getEngine()
|
engine := c.getEngine()
|
||||||
|
|
||||||
return fmt.Sprintf("{ChainID: %v, Homestead: %v, DAO: %v, Tangerine Whistle: %v, Spurious Dragon: %v, Byzantium: %v, Constantinople: %v, Petersburg: %v, Istanbul: %v, Muir Glacier: %v, Berlin: %v, London: %v, Arrow Glacier: %v, Gray Glacier: %v, Terminal Total Difficulty: %v, Merge Netsplit: %v, Shanghai: %v, Cancun: %v, Prague: %v, Engine: %v}",
|
return fmt.Sprintf("{ChainID: %v, Homestead: %v, DAO: %v, Tangerine Whistle: %v, Spurious Dragon: %v, Byzantium: %v, Constantinople: %v, Petersburg: %v, Istanbul: %v, Muir Glacier: %v, Berlin: %v, London: %v, Arrow Glacier: %v, Gray Glacier: %v, Primordial Pulse: %v, Terminal Total Difficulty: %v, Merge Netsplit: %v, Shanghai: %v, Cancun: %v, Prague: %v, Engine: %v}",
|
||||||
c.ChainID,
|
c.ChainID,
|
||||||
c.HomesteadBlock,
|
c.HomesteadBlock,
|
||||||
c.DAOForkBlock,
|
c.DAOForkBlock,
|
||||||
@ -112,6 +117,7 @@ func (c *Config) String() string {
|
|||||||
c.LondonBlock,
|
c.LondonBlock,
|
||||||
c.ArrowGlacierBlock,
|
c.ArrowGlacierBlock,
|
||||||
c.GrayGlacierBlock,
|
c.GrayGlacierBlock,
|
||||||
|
c.PrimordialPulseBlock,
|
||||||
c.TerminalTotalDifficulty,
|
c.TerminalTotalDifficulty,
|
||||||
c.MergeNetsplitBlock,
|
c.MergeNetsplitBlock,
|
||||||
c.ShanghaiTime,
|
c.ShanghaiTime,
|
||||||
@ -231,6 +237,17 @@ func (c *Config) IsPrague(time uint64) bool {
|
|||||||
return isForked(c.PragueTime, time)
|
return isForked(c.PragueTime, time)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsPrimordialPulseBlock returns whether or not the given block is the primordial pulse block.
|
||||||
|
func (c *Config) IsPrimordialPulseBlock(number uint64) bool {
|
||||||
|
return c.PrimordialPulseBlock != nil && c.PrimordialPulseBlock.Uint64() == number
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrimordialPulseAhead Returns true if there is a PrimordialPulse block in the future, indicating this chain
|
||||||
|
// should still be evaluated using the ethash consensus engine and with mainnet ChainID.
|
||||||
|
func (c *Config) PrimordialPulseAhead(number uint64) bool {
|
||||||
|
return c.PrimordialPulseBlock != nil && c.PrimordialPulseBlock.Uint64() > number
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Config) GetBurntContract(num uint64) *common.Address {
|
func (c *Config) GetBurntContract(num uint64) *common.Address {
|
||||||
if len(c.BurntContract) == 0 {
|
if len(c.BurntContract) == 0 {
|
||||||
return nil
|
return nil
|
||||||
@ -363,7 +380,8 @@ func (c *Config) checkCompatible(newcfg *Config, head uint64) *ConfigCompatError
|
|||||||
if incompatible(c.SpuriousDragonBlock, newcfg.SpuriousDragonBlock, head) {
|
if incompatible(c.SpuriousDragonBlock, newcfg.SpuriousDragonBlock, head) {
|
||||||
return newCompatError("Spurious Dragon fork block", c.SpuriousDragonBlock, newcfg.SpuriousDragonBlock)
|
return newCompatError("Spurious Dragon fork block", c.SpuriousDragonBlock, newcfg.SpuriousDragonBlock)
|
||||||
}
|
}
|
||||||
if c.IsSpuriousDragon(head) && !numEqual(c.ChainID, newcfg.ChainID) {
|
// allow mismatching ChainID if there is a PrimordialPulse block ahead
|
||||||
|
if c.IsSpuriousDragon(head) && !numEqual(c.ChainID, newcfg.ChainID) && !newcfg.PrimordialPulseAhead(head) {
|
||||||
return newCompatError("EIP155 chain ID", c.SpuriousDragonBlock, newcfg.SpuriousDragonBlock)
|
return newCompatError("EIP155 chain ID", c.SpuriousDragonBlock, newcfg.SpuriousDragonBlock)
|
||||||
}
|
}
|
||||||
if incompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, head) {
|
if incompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, head) {
|
||||||
@ -400,6 +418,9 @@ func (c *Config) checkCompatible(newcfg *Config, head uint64) *ConfigCompatError
|
|||||||
if incompatible(c.MergeNetsplitBlock, newcfg.MergeNetsplitBlock, head) {
|
if incompatible(c.MergeNetsplitBlock, newcfg.MergeNetsplitBlock, head) {
|
||||||
return newCompatError("Merge netsplit block", c.MergeNetsplitBlock, newcfg.MergeNetsplitBlock)
|
return newCompatError("Merge netsplit block", c.MergeNetsplitBlock, newcfg.MergeNetsplitBlock)
|
||||||
}
|
}
|
||||||
|
if incompatible(c.PrimordialPulseBlock, newcfg.PrimordialPulseBlock, head) {
|
||||||
|
return newCompatError("PrimordialPulse fork block", c.PrimordialPulseBlock, newcfg.PrimordialPulseBlock)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -506,6 +527,12 @@ func (c *Config) Rules(num uint64, time uint64) *Rules {
|
|||||||
if chainID == nil {
|
if chainID == nil {
|
||||||
chainID = new(big.Int)
|
chainID = new(big.Int)
|
||||||
}
|
}
|
||||||
|
isShanghai := c.IsShanghai(time)
|
||||||
|
if c.PrimordialPulseAhead(num) {
|
||||||
|
// If the PrimordialPulse fork is ahead, derive the `isShanghai` rule
|
||||||
|
// from the Ethereum Mainnet Shanghai timestamp.
|
||||||
|
isShanghai = time >= 1681338455
|
||||||
|
}
|
||||||
|
|
||||||
return &Rules{
|
return &Rules{
|
||||||
ChainID: new(big.Int).Set(chainID),
|
ChainID: new(big.Int).Set(chainID),
|
||||||
@ -518,7 +545,7 @@ func (c *Config) Rules(num uint64, time uint64) *Rules {
|
|||||||
IsIstanbul: c.IsIstanbul(num),
|
IsIstanbul: c.IsIstanbul(num),
|
||||||
IsBerlin: c.IsBerlin(num),
|
IsBerlin: c.IsBerlin(num),
|
||||||
IsLondon: c.IsLondon(num),
|
IsLondon: c.IsLondon(num),
|
||||||
IsShanghai: c.IsShanghai(time) || c.IsAgra(num),
|
IsShanghai: isShanghai || c.IsAgra(num),
|
||||||
IsCancun: c.IsCancun(time),
|
IsCancun: c.IsCancun(time),
|
||||||
IsNapoli: c.IsNapoli(num),
|
IsNapoli: c.IsNapoli(num),
|
||||||
IsPrague: c.IsPrague(time),
|
IsPrague: c.IsPrague(time),
|
||||||
|
@ -13,6 +13,8 @@ const (
|
|||||||
GnosisChainName = "gnosis"
|
GnosisChainName = "gnosis"
|
||||||
BorE2ETestChain2ValName = "bor-e2e-test-2Val"
|
BorE2ETestChain2ValName = "bor-e2e-test-2Val"
|
||||||
ChiadoChainName = "chiado"
|
ChiadoChainName = "chiado"
|
||||||
|
PulsechainChainName = "pulsechain"
|
||||||
|
PulsechainTestnetChainName = "pulsechain-testnet"
|
||||||
)
|
)
|
||||||
|
|
||||||
var All = []string{
|
var All = []string{
|
||||||
@ -26,4 +28,6 @@ var All = []string{
|
|||||||
BorDevnetChainName,
|
BorDevnetChainName,
|
||||||
GnosisChainName,
|
GnosisChainName,
|
||||||
ChiadoChainName,
|
ChiadoChainName,
|
||||||
|
PulsechainChainName,
|
||||||
|
PulsechainTestnetChainName,
|
||||||
}
|
}
|
||||||
|
25
erigon-lib/chain/pulsechain_config.go
Normal file
25
erigon-lib/chain/pulsechain_config.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package chain
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PulseChainConfig struct {
|
||||||
|
// An optional treasury which will receive allocations during the PrimordialPulseBlock.
|
||||||
|
Treasury *PulseChainTreasury `json:"treasury,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements the stringer interface, returning the consensus engine details.
|
||||||
|
func (b *PulseChainConfig) String() string {
|
||||||
|
return "PulseChain"
|
||||||
|
}
|
||||||
|
|
||||||
|
// PulseChainTreasury represents an optional treasury for launching PulseChain testnets.
|
||||||
|
type PulseChainTreasury struct {
|
||||||
|
Addr string `json:"addr"`
|
||||||
|
Balance string `json:"balance"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PulseChainTTDOffset is a trivially small amount of work added to the Ethereum Mainnet TTD
|
||||||
|
// to allow for un-merging and merging with the PulseChain beacon chain.
|
||||||
|
var PulseChainTTDOffset = big.NewInt(131_072)
|
@ -10,6 +10,7 @@ import (
|
|||||||
snapshothashes "github.com/ledgerwatch/erigon-snapshot"
|
snapshothashes "github.com/ledgerwatch/erigon-snapshot"
|
||||||
"github.com/ledgerwatch/erigon-snapshot/webseed"
|
"github.com/ledgerwatch/erigon-snapshot/webseed"
|
||||||
"github.com/pelletier/go-toml/v2"
|
"github.com/pelletier/go-toml/v2"
|
||||||
|
pulseSnapshotHashes "gitlab.com/pulsechaincom/erigon-pulse-snapshot"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -23,6 +24,8 @@ var (
|
|||||||
BorMainnet = fromToml(snapshothashes.BorMainnet)
|
BorMainnet = fromToml(snapshothashes.BorMainnet)
|
||||||
Gnosis = fromToml(snapshothashes.Gnosis)
|
Gnosis = fromToml(snapshothashes.Gnosis)
|
||||||
Chiado = fromToml(snapshothashes.Chiado)
|
Chiado = fromToml(snapshothashes.Chiado)
|
||||||
|
PulseChainMainnet = fromToml(pulseSnapshotHashes.PulseChainMainnet)
|
||||||
|
PulseChainTestnet = fromToml(snapshothashes.Mainnet)
|
||||||
)
|
)
|
||||||
|
|
||||||
type PreverifiedItem struct {
|
type PreverifiedItem struct {
|
||||||
@ -144,6 +147,8 @@ var knownPreverified = map[string]Preverified{
|
|||||||
networkname.BorMainnetChainName: BorMainnet,
|
networkname.BorMainnetChainName: BorMainnet,
|
||||||
networkname.GnosisChainName: Gnosis,
|
networkname.GnosisChainName: Gnosis,
|
||||||
networkname.ChiadoChainName: Chiado,
|
networkname.ChiadoChainName: Chiado,
|
||||||
|
networkname.PulsechainChainName: PulseChainMainnet,
|
||||||
|
networkname.PulsechainTestnetChainName: PulseChainTestnet,
|
||||||
}
|
}
|
||||||
|
|
||||||
// KnownCfg return list of preverified hashes for given network, but apply whiteList filter if it's not empty
|
// KnownCfg return list of preverified hashes for given network, but apply whiteList filter if it's not empty
|
||||||
|
@ -74,8 +74,8 @@ func NewFetch(ctx context.Context, sentryClients []direct.SentryClient, pool Poo
|
|||||||
coreDB: coreDB,
|
coreDB: coreDB,
|
||||||
db: db,
|
db: db,
|
||||||
stateChangesClient: stateChangesClient,
|
stateChangesClient: stateChangesClient,
|
||||||
stateChangesParseCtx: types2.NewTxParseContext(chainID).ChainIDRequired(), //TODO: change ctx if rules changed
|
stateChangesParseCtx: types2.NewTxParseContext(chainID, false).ChainIDRequired(), //TODO: change ctx if rules changed
|
||||||
pooledTxsParseCtx: types2.NewTxParseContext(chainID).ChainIDRequired(),
|
pooledTxsParseCtx: types2.NewTxParseContext(chainID, false).ChainIDRequired(),
|
||||||
logger: logger,
|
logger: logger,
|
||||||
}
|
}
|
||||||
f.pooledTxsParseCtx.ValidateRLP(f.pool.ValidateSerializedTxn)
|
f.pooledTxsParseCtx.ValidateRLP(f.pool.ValidateSerializedTxn)
|
||||||
|
@ -46,7 +46,7 @@ func TestFetch(t *testing.T) {
|
|||||||
sentryClient := direct.NewSentryClientDirect(direct.ETH66, m)
|
sentryClient := direct.NewSentryClientDirect(direct.ETH66, m)
|
||||||
pool := &PoolMock{}
|
pool := &PoolMock{}
|
||||||
|
|
||||||
fetch := NewFetch(ctx, []direct.SentryClient{sentryClient}, pool, &remote.KVClientMock{}, nil, nil, *u256.N1, log.New())
|
fetch := NewFetch(ctx, []direct.SentryClient{sentryClient}, pool, &remote.KVClientMock{}, nil, nil, *u256.N1, log.New(), false)
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
fetch.SetWaitGroup(&wg)
|
fetch.SetWaitGroup(&wg)
|
||||||
m.StreamWg.Add(2)
|
m.StreamWg.Add(2)
|
||||||
@ -184,7 +184,7 @@ func TestOnNewBlock(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
pool := &PoolMock{}
|
pool := &PoolMock{}
|
||||||
fetch := NewFetch(ctx, nil, pool, stateChanges, coreDB, db, *u256.N1, log.New())
|
fetch := NewFetch(ctx, nil, pool, stateChanges, coreDB, db, *u256.N1, log.New(), false)
|
||||||
err := fetch.handleStateChanges(ctx, stateChanges)
|
err := fetch.handleStateChanges(ctx, stateChanges)
|
||||||
assert.ErrorIs(t, io.EOF, err)
|
assert.ErrorIs(t, io.EOF, err)
|
||||||
assert.Equal(t, 1, len(pool.OnNewBlockCalls()))
|
assert.Equal(t, 1, len(pool.OnNewBlockCalls()))
|
||||||
|
@ -654,7 +654,7 @@ func (p *TxPool) getCachedBlobTxnLocked(tx kv.Tx, hash []byte) (*metaTx, error)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
parseCtx := types.NewTxParseContext(p.chainID)
|
parseCtx := types.NewTxParseContext(p.chainID, false)
|
||||||
parseCtx.WithSender(false)
|
parseCtx.WithSender(false)
|
||||||
txSlot := &types.TxSlot{}
|
txSlot := &types.TxSlot{}
|
||||||
parseCtx.ParseTransaction(txn, 0, txSlot, nil, false, true, nil)
|
parseCtx.ParseTransaction(txn, 0, txSlot, nil, false, true, nil)
|
||||||
@ -2048,7 +2048,7 @@ func (p *TxPool) fromDB(ctx context.Context, tx kv.Tx, coreTx kv.Tx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
txs := types.TxSlots{}
|
txs := types.TxSlots{}
|
||||||
parseCtx := types.NewTxParseContext(p.chainID)
|
parseCtx := types.NewTxParseContext(p.chainID, false)
|
||||||
parseCtx.WithSender(false)
|
parseCtx.WithSender(false)
|
||||||
|
|
||||||
i := 0
|
i := 0
|
||||||
|
@ -199,7 +199,7 @@ func poolsFromFuzzBytes(rawTxNonce, rawValues, rawTips, rawFeeCap, rawSender []b
|
|||||||
senderIDs[senders.AddressAt(i%senders.Len())] = senderID
|
senderIDs[senders.AddressAt(i%senders.Len())] = senderID
|
||||||
}
|
}
|
||||||
txs.Txs = make([]*types.TxSlot, len(txNonce))
|
txs.Txs = make([]*types.TxSlot, len(txNonce))
|
||||||
parseCtx := types.NewTxParseContext(*u256.N1)
|
parseCtx := types.NewTxParseContext(*u256.N1, false)
|
||||||
parseCtx.WithSender(false)
|
parseCtx.WithSender(false)
|
||||||
for i := range txNonce {
|
for i := range txNonce {
|
||||||
txs.Txs[i] = &types.TxSlot{
|
txs.Txs[i] = &types.TxSlot{
|
||||||
@ -314,7 +314,7 @@ func FuzzOnNewBlocks(f *testing.F) {
|
|||||||
|
|
||||||
cfg := txpoolcfg.DefaultConfig
|
cfg := txpoolcfg.DefaultConfig
|
||||||
sendersCache := kvcache.New(kvcache.DefaultCoherentConfig)
|
sendersCache := kvcache.New(kvcache.DefaultCoherentConfig)
|
||||||
pool, err := New(ch, coreDB, cfg, sendersCache, *u256.N1, nil, nil, nil, fixedgas.DefaultMaxBlobsPerBlock, nil, log.New())
|
pool, err := New(ch, coreDB, cfg, sendersCache, *u256.N1, nil, nil, nil, fixedgas.DefaultMaxBlobsPerBlock, nil, log.New(), false)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
err = pool.Start(ctx, db)
|
err = pool.Start(ctx, db)
|
||||||
@ -540,7 +540,7 @@ func FuzzOnNewBlocks(f *testing.F) {
|
|||||||
check(p2pReceived, types.TxSlots{}, "after_flush")
|
check(p2pReceived, types.TxSlots{}, "after_flush")
|
||||||
checkNotify(p2pReceived, types.TxSlots{}, "after_flush")
|
checkNotify(p2pReceived, types.TxSlots{}, "after_flush")
|
||||||
|
|
||||||
p2, err := New(ch, coreDB, txpoolcfg.DefaultConfig, sendersCache, *u256.N1, nil, nil, nil, fixedgas.DefaultMaxBlobsPerBlock, nil, log.New())
|
p2, err := New(ch, coreDB, txpoolcfg.DefaultConfig, sendersCache, *u256.N1, nil, nil, nil, fixedgas.DefaultMaxBlobsPerBlock, nil, log.New(), false)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
p2.senders = pool.senders // senders are not persisted
|
p2.senders = pool.senders // senders are not persisted
|
||||||
|
@ -53,7 +53,7 @@ func TestNonceFromAddress(t *testing.T) {
|
|||||||
|
|
||||||
cfg := txpoolcfg.DefaultConfig
|
cfg := txpoolcfg.DefaultConfig
|
||||||
sendersCache := kvcache.New(kvcache.DefaultCoherentConfig)
|
sendersCache := kvcache.New(kvcache.DefaultCoherentConfig)
|
||||||
pool, err := New(ch, coreDB, cfg, sendersCache, *u256.N1, nil, nil, nil, fixedgas.DefaultMaxBlobsPerBlock, nil, log.New())
|
pool, err := New(ch, coreDB, cfg, sendersCache, *u256.N1, nil, nil, nil, fixedgas.DefaultMaxBlobsPerBlock, nil, log.New(), false)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
require.True(pool != nil)
|
require.True(pool != nil)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
@ -173,7 +173,7 @@ func TestReplaceWithHigherFee(t *testing.T) {
|
|||||||
|
|
||||||
cfg := txpoolcfg.DefaultConfig
|
cfg := txpoolcfg.DefaultConfig
|
||||||
sendersCache := kvcache.New(kvcache.DefaultCoherentConfig)
|
sendersCache := kvcache.New(kvcache.DefaultCoherentConfig)
|
||||||
pool, err := New(ch, coreDB, cfg, sendersCache, *u256.N1, nil, nil, nil, fixedgas.DefaultMaxBlobsPerBlock, nil, log.New())
|
pool, err := New(ch, coreDB, cfg, sendersCache, *u256.N1, nil, nil, nil, fixedgas.DefaultMaxBlobsPerBlock, nil, log.New(), false)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
require.NotEqual(nil, pool)
|
require.NotEqual(nil, pool)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
@ -290,7 +290,7 @@ func TestReverseNonces(t *testing.T) {
|
|||||||
|
|
||||||
cfg := txpoolcfg.DefaultConfig
|
cfg := txpoolcfg.DefaultConfig
|
||||||
sendersCache := kvcache.New(kvcache.DefaultCoherentConfig)
|
sendersCache := kvcache.New(kvcache.DefaultCoherentConfig)
|
||||||
pool, err := New(ch, coreDB, cfg, sendersCache, *u256.N1, nil, nil, nil, fixedgas.DefaultMaxBlobsPerBlock, nil, log.New())
|
pool, err := New(ch, coreDB, cfg, sendersCache, *u256.N1, nil, nil, nil, fixedgas.DefaultMaxBlobsPerBlock, nil, log.New(), false)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
require.True(pool != nil)
|
require.True(pool != nil)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
@ -417,7 +417,7 @@ func TestTxPoke(t *testing.T) {
|
|||||||
|
|
||||||
cfg := txpoolcfg.DefaultConfig
|
cfg := txpoolcfg.DefaultConfig
|
||||||
sendersCache := kvcache.New(kvcache.DefaultCoherentConfig)
|
sendersCache := kvcache.New(kvcache.DefaultCoherentConfig)
|
||||||
pool, err := New(ch, coreDB, cfg, sendersCache, *u256.N1, nil, nil, nil, fixedgas.DefaultMaxBlobsPerBlock, nil, log.New())
|
pool, err := New(ch, coreDB, cfg, sendersCache, *u256.N1, nil, nil, nil, fixedgas.DefaultMaxBlobsPerBlock, nil, log.New(), false)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
require.True(pool != nil)
|
require.True(pool != nil)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
@ -682,7 +682,7 @@ func TestShanghaiValidateTx(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cache := &kvcache.DummyCache{}
|
cache := &kvcache.DummyCache{}
|
||||||
pool, err := New(ch, coreDB, cfg, cache, *u256.N1, shanghaiTime, nil /* agraBlock */, nil /* cancunTime */, fixedgas.DefaultMaxBlobsPerBlock, nil, logger)
|
pool, err := New(ch, coreDB, cfg, cache, *u256.N1, shanghaiTime, nil /* agraBlock */, nil /* cancunTime */, fixedgas.DefaultMaxBlobsPerBlock, nil, logger, false)
|
||||||
asrt.NoError(err)
|
asrt.NoError(err)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
tx, err := coreDB.BeginRw(ctx)
|
tx, err := coreDB.BeginRw(ctx)
|
||||||
@ -728,7 +728,7 @@ func TestBlobTxReplacement(t *testing.T) {
|
|||||||
db, coreDB := memdb.NewTestPoolDB(t), memdb.NewTestDB(t)
|
db, coreDB := memdb.NewTestPoolDB(t), memdb.NewTestDB(t)
|
||||||
cfg := txpoolcfg.DefaultConfig
|
cfg := txpoolcfg.DefaultConfig
|
||||||
sendersCache := kvcache.New(kvcache.DefaultCoherentConfig)
|
sendersCache := kvcache.New(kvcache.DefaultCoherentConfig)
|
||||||
pool, err := New(ch, coreDB, cfg, sendersCache, *u256.N1, common.Big0, nil, common.Big0, fixedgas.DefaultMaxBlobsPerBlock, nil, log.New())
|
pool, err := New(ch, coreDB, cfg, sendersCache, *u256.N1, common.Big0, nil, common.Big0, fixedgas.DefaultMaxBlobsPerBlock, nil, log.New(), false)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
require.True(pool != nil)
|
require.True(pool != nil)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
@ -929,7 +929,7 @@ func makeBlobTx() types.TxSlot {
|
|||||||
tip, feeCap, blobFeeCap := uint256.NewInt(100_000), uint256.NewInt(200_000), uint256.NewInt(200_000)
|
tip, feeCap, blobFeeCap := uint256.NewInt(100_000), uint256.NewInt(200_000), uint256.NewInt(200_000)
|
||||||
|
|
||||||
blobTx := types.TxSlot{}
|
blobTx := types.TxSlot{}
|
||||||
tctx := types.NewTxParseContext(*uint256.NewInt(5))
|
tctx := types.NewTxParseContext(*uint256.NewInt(5), false)
|
||||||
tctx.WithSender(false)
|
tctx.WithSender(false)
|
||||||
tctx.ParseTransaction(wrapperRlp, 0, &blobTx, nil, false, true, nil)
|
tctx.ParseTransaction(wrapperRlp, 0, &blobTx, nil, false, true, nil)
|
||||||
blobTx.BlobHashes = make([]common.Hash, 2)
|
blobTx.BlobHashes = make([]common.Hash, 2)
|
||||||
|
@ -182,7 +182,7 @@ func (s *GrpcServer) Add(ctx context.Context, in *txpool_proto.AddRequest) (*txp
|
|||||||
defer tx.Rollback()
|
defer tx.Rollback()
|
||||||
|
|
||||||
var slots types.TxSlots
|
var slots types.TxSlots
|
||||||
parseCtx := types.NewTxParseContext(s.chainID).ChainIDRequired()
|
parseCtx := types.NewTxParseContext(s.chainID, false).ChainIDRequired()
|
||||||
parseCtx.ValidateRLP(s.txPool.ValidateSerializedTxn)
|
parseCtx.ValidateRLP(s.txPool.ValidateSerializedTxn)
|
||||||
|
|
||||||
reply := &txpool_proto.AddReply{Imported: make([]txpool_proto.ImportResult, len(in.RlpTxs)), Errors: make([]string, len(in.RlpTxs))}
|
reply := &txpool_proto.AddReply{Imported: make([]txpool_proto.ImportResult, len(in.RlpTxs)), Errors: make([]string, len(in.RlpTxs))}
|
||||||
|
@ -64,9 +64,10 @@ type TxParseContext struct {
|
|||||||
allowPreEip2s bool // Allow s > secp256k1n/2; see EIP-2
|
allowPreEip2s bool // Allow s > secp256k1n/2; see EIP-2
|
||||||
chainIDRequired bool
|
chainIDRequired bool
|
||||||
IsProtected bool
|
IsProtected bool
|
||||||
|
allowPulseChainLegacy bool // If allowPulseChainLegacy is true, allow prefork transactions from the Ethereum Mainnet chain.
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTxParseContext(chainID uint256.Int) *TxParseContext {
|
func NewTxParseContext(chainID uint256.Int, allowPulseChainLegacy bool) *TxParseContext {
|
||||||
if chainID.IsZero() {
|
if chainID.IsZero() {
|
||||||
panic("wrong chainID")
|
panic("wrong chainID")
|
||||||
}
|
}
|
||||||
@ -74,6 +75,7 @@ func NewTxParseContext(chainID uint256.Int) *TxParseContext {
|
|||||||
withSender: true,
|
withSender: true,
|
||||||
Keccak1: sha3.NewLegacyKeccak256(),
|
Keccak1: sha3.NewLegacyKeccak256(),
|
||||||
Keccak2: sha3.NewLegacyKeccak256(),
|
Keccak2: sha3.NewLegacyKeccak256(),
|
||||||
|
allowPulseChainLegacy: allowPulseChainLegacy,
|
||||||
}
|
}
|
||||||
|
|
||||||
// behave as of London enabled
|
// behave as of London enabled
|
||||||
@ -337,8 +339,14 @@ func (ctx *TxParseContext) parseTransactionBody(payload []byte, pos, p0 int, slo
|
|||||||
ctx.ChainID.Set(&ctx.cfg.ChainID)
|
ctx.ChainID.Set(&ctx.cfg.ChainID)
|
||||||
}
|
}
|
||||||
if !ctx.ChainID.Eq(&ctx.cfg.ChainID) {
|
if !ctx.ChainID.Eq(&ctx.cfg.ChainID) {
|
||||||
|
if !ctx.allowPulseChainLegacy {
|
||||||
return 0, fmt.Errorf("%w: %s, %d (expected %d)", ErrParseTxn, "invalid chainID", ctx.ChainID.Uint64(), ctx.cfg.ChainID.Uint64())
|
return 0, fmt.Errorf("%w: %s, %d (expected %d)", ErrParseTxn, "invalid chainID", ctx.ChainID.Uint64(), ctx.cfg.ChainID.Uint64())
|
||||||
}
|
}
|
||||||
|
// If allowPulseChainLegacy, ChainID must be 1 (Ethereum Mainnet).
|
||||||
|
if !ctx.ChainID.Eq(uint256.NewInt(1)) {
|
||||||
|
return 0, fmt.Errorf("%w: %s, %d (expected %d)", ErrParseTxn, "invalid PulseChain chainID", ctx.ChainID.Uint64(), ctx.cfg.ChainID.Uint64())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Next follows the nonce, which we need to parse
|
// Next follows the nonce, which we need to parse
|
||||||
p, slot.Nonce, err = rlp.U64(payload, p)
|
p, slot.Nonce, err = rlp.U64(payload, p)
|
||||||
@ -486,8 +494,14 @@ func (ctx *TxParseContext) parseTransactionBody(payload []byte, pos, p0 int, slo
|
|||||||
ctx.ChainID.Sub(&ctx.V, u256.N35)
|
ctx.ChainID.Sub(&ctx.V, u256.N35)
|
||||||
ctx.ChainID.Rsh(&ctx.ChainID, 1)
|
ctx.ChainID.Rsh(&ctx.ChainID, 1)
|
||||||
if !ctx.ChainID.Eq(&ctx.cfg.ChainID) {
|
if !ctx.ChainID.Eq(&ctx.cfg.ChainID) {
|
||||||
|
if !ctx.allowPulseChainLegacy {
|
||||||
return 0, fmt.Errorf("%w: %s, %d (expected %d)", ErrParseTxn, "invalid chainID", ctx.ChainID.Uint64(), ctx.cfg.ChainID.Uint64())
|
return 0, fmt.Errorf("%w: %s, %d (expected %d)", ErrParseTxn, "invalid chainID", ctx.ChainID.Uint64(), ctx.cfg.ChainID.Uint64())
|
||||||
}
|
}
|
||||||
|
// If allowPulseChainLegacy, ChainID must be 1 (Ethereum Mainnet).
|
||||||
|
if !ctx.ChainID.Eq(uint256.NewInt(1)) {
|
||||||
|
return 0, fmt.Errorf("%w: %s, %d (expected %d)", ErrParseTxn, "invalid PulseChain chainID", ctx.ChainID.Uint64(), ctx.cfg.ChainID.Uint64())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
chainIDBits = ctx.ChainID.BitLen()
|
chainIDBits = ctx.ChainID.BitLen()
|
||||||
if chainIDBits <= 7 {
|
if chainIDBits <= 7 {
|
||||||
|
@ -16,7 +16,7 @@ func FuzzPooledTransactions66(f *testing.F) {
|
|||||||
f.Add(hexutility.MustDecodeHex("e8bfffffffffffffffffffffffff71e866666666955ef90c91f9fa08f96ebfbfbf007d765059effe33"))
|
f.Add(hexutility.MustDecodeHex("e8bfffffffffffffffffffffffff71e866666666955ef90c91f9fa08f96ebfbfbf007d765059effe33"))
|
||||||
f.Fuzz(func(t *testing.T, in []byte) {
|
f.Fuzz(func(t *testing.T, in []byte) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
ctx := NewTxParseContext(*u256.N1)
|
ctx := NewTxParseContext(*u256.N1, false)
|
||||||
slots := TxSlots{}
|
slots := TxSlots{}
|
||||||
reqId, _, err := ParsePooledTransactions66(in, 0, ctx, &slots, nil)
|
reqId, _, err := ParsePooledTransactions66(in, 0, ctx, &slots, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -143,7 +143,7 @@ func TestPooledTransactionsPacket66(t *testing.T) {
|
|||||||
encodeBuf = EncodePooledTransactions66(tt.txs, tt.requestID, encodeBuf)
|
encodeBuf = EncodePooledTransactions66(tt.txs, tt.requestID, encodeBuf)
|
||||||
require.Equal(tt.encoded, fmt.Sprintf("%x", encodeBuf))
|
require.Equal(tt.encoded, fmt.Sprintf("%x", encodeBuf))
|
||||||
|
|
||||||
ctx := NewTxParseContext(*uint256.NewInt(tt.chainID))
|
ctx := NewTxParseContext(*uint256.NewInt(tt.chainID), false)
|
||||||
slots := &TxSlots{}
|
slots := &TxSlots{}
|
||||||
requestID, _, err := ParsePooledTransactions66(encodeBuf, 0, ctx, slots, nil)
|
requestID, _, err := ParsePooledTransactions66(encodeBuf, 0, ctx, slots, nil)
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
@ -162,7 +162,7 @@ func TestPooledTransactionsPacket66(t *testing.T) {
|
|||||||
require.Equal(tt.encoded, fmt.Sprintf("%x", encodeBuf))
|
require.Equal(tt.encoded, fmt.Sprintf("%x", encodeBuf))
|
||||||
|
|
||||||
chainID := uint256.NewInt(tt.chainID)
|
chainID := uint256.NewInt(tt.chainID)
|
||||||
ctx := NewTxParseContext(*chainID)
|
ctx := NewTxParseContext(*chainID, false)
|
||||||
slots := &TxSlots{}
|
slots := &TxSlots{}
|
||||||
requestID, _, err := ParsePooledTransactions66(encodeBuf, 0, ctx, slots, func(bytes []byte) error { return ErrRejected })
|
requestID, _, err := ParsePooledTransactions66(encodeBuf, 0, ctx, slots, func(bytes []byte) error { return ErrRejected })
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
@ -203,7 +203,7 @@ func TestTransactionsPacket(t *testing.T) {
|
|||||||
encodeBuf = EncodeTransactions(tt.txs, encodeBuf)
|
encodeBuf = EncodeTransactions(tt.txs, encodeBuf)
|
||||||
require.Equal(tt.encoded, fmt.Sprintf("%x", encodeBuf))
|
require.Equal(tt.encoded, fmt.Sprintf("%x", encodeBuf))
|
||||||
|
|
||||||
ctx := NewTxParseContext(*uint256.NewInt(tt.chainID))
|
ctx := NewTxParseContext(*uint256.NewInt(tt.chainID), false)
|
||||||
slots := &TxSlots{}
|
slots := &TxSlots{}
|
||||||
_, err := ParseTransactions(encodeBuf, 0, ctx, slots, nil)
|
_, err := ParseTransactions(encodeBuf, 0, ctx, slots, nil)
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
@ -221,7 +221,7 @@ func TestTransactionsPacket(t *testing.T) {
|
|||||||
require.Equal(tt.encoded, fmt.Sprintf("%x", encodeBuf))
|
require.Equal(tt.encoded, fmt.Sprintf("%x", encodeBuf))
|
||||||
|
|
||||||
chainID := uint256.NewInt(tt.chainID)
|
chainID := uint256.NewInt(tt.chainID)
|
||||||
ctx := NewTxParseContext(*chainID)
|
ctx := NewTxParseContext(*chainID, false)
|
||||||
slots := &TxSlots{}
|
slots := &TxSlots{}
|
||||||
_, err := ParseTransactions(encodeBuf, 0, ctx, slots, func(bytes []byte) error { return ErrRejected })
|
_, err := ParseTransactions(encodeBuf, 0, ctx, slots, func(bytes []byte) error { return ErrRejected })
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
|
@ -36,7 +36,7 @@ func TestParseTransactionRLP(t *testing.T) {
|
|||||||
testSet := testSet
|
testSet := testSet
|
||||||
t.Run(strconv.Itoa(int(testSet.chainID.Uint64())), func(t *testing.T) {
|
t.Run(strconv.Itoa(int(testSet.chainID.Uint64())), func(t *testing.T) {
|
||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
ctx := NewTxParseContext(testSet.chainID)
|
ctx := NewTxParseContext(testSet.chainID, false)
|
||||||
tx, txSender := &TxSlot{}, [20]byte{}
|
tx, txSender := &TxSlot{}, [20]byte{}
|
||||||
for i, tt := range testSet.tests {
|
for i, tt := range testSet.tests {
|
||||||
tt := tt
|
tt := tt
|
||||||
@ -72,7 +72,7 @@ func TestParseTransactionRLP(t *testing.T) {
|
|||||||
|
|
||||||
func TestTransactionSignatureValidity1(t *testing.T) {
|
func TestTransactionSignatureValidity1(t *testing.T) {
|
||||||
chainId := new(uint256.Int).SetUint64(1)
|
chainId := new(uint256.Int).SetUint64(1)
|
||||||
ctx := NewTxParseContext(*chainId)
|
ctx := NewTxParseContext(*chainId, false)
|
||||||
ctx.WithAllowPreEip2s(true)
|
ctx.WithAllowPreEip2s(true)
|
||||||
|
|
||||||
tx, txSender := &TxSlot{}, [20]byte{}
|
tx, txSender := &TxSlot{}, [20]byte{}
|
||||||
@ -96,7 +96,7 @@ func TestTransactionSignatureValidity1(t *testing.T) {
|
|||||||
// Problematic txn included in a bad block on Görli
|
// Problematic txn included in a bad block on Görli
|
||||||
func TestTransactionSignatureValidity2(t *testing.T) {
|
func TestTransactionSignatureValidity2(t *testing.T) {
|
||||||
chainId := new(uint256.Int).SetUint64(5)
|
chainId := new(uint256.Int).SetUint64(5)
|
||||||
ctx := NewTxParseContext(*chainId)
|
ctx := NewTxParseContext(*chainId, false)
|
||||||
slot, sender := &TxSlot{}, [20]byte{}
|
slot, sender := &TxSlot{}, [20]byte{}
|
||||||
rlp := hexutility.MustDecodeHex("02f8720513844190ab00848321560082520894cab441d2f45a3fee83d15c6b6b6c36a139f55b6288054607fc96a6000080c001a0dffe4cb5651e663d0eac8c4d002de734dd24db0f1109b062d17da290a133cc02a0913fb9f53f7a792bcd9e4d7cced1b8545d1ab82c77432b0bc2e9384ba6c250c5")
|
rlp := hexutility.MustDecodeHex("02f8720513844190ab00848321560082520894cab441d2f45a3fee83d15c6b6b6c36a139f55b6288054607fc96a6000080c001a0dffe4cb5651e663d0eac8c4d002de734dd24db0f1109b062d17da290a133cc02a0913fb9f53f7a792bcd9e4d7cced1b8545d1ab82c77432b0bc2e9384ba6c250c5")
|
||||||
_, err := ctx.ParseTransaction(rlp, 0, slot, sender[:], false /* hasEnvelope */, true /* wrappedWithBlobs */, nil)
|
_, err := ctx.ParseTransaction(rlp, 0, slot, sender[:], false /* hasEnvelope */, true /* wrappedWithBlobs */, nil)
|
||||||
@ -200,7 +200,7 @@ func TestBlobTxParsing(t *testing.T) {
|
|||||||
bodyEnvelope = append(bodyEnvelope, BlobTxType)
|
bodyEnvelope = append(bodyEnvelope, BlobTxType)
|
||||||
bodyEnvelope = append(bodyEnvelope, bodyRlp...)
|
bodyEnvelope = append(bodyEnvelope, bodyRlp...)
|
||||||
|
|
||||||
ctx := NewTxParseContext(*uint256.NewInt(5))
|
ctx := NewTxParseContext(*uint256.NewInt(5), false)
|
||||||
ctx.withSender = false
|
ctx.withSender = false
|
||||||
|
|
||||||
var thinTx TxSlot // only tx body, no blobs
|
var thinTx TxSlot // only tx body, no blobs
|
||||||
|
@ -24,7 +24,7 @@ func FuzzParseTx(f *testing.F) {
|
|||||||
f.Add([]byte{1}, 0)
|
f.Add([]byte{1}, 0)
|
||||||
f.Fuzz(func(t *testing.T, in []byte, pos int) {
|
f.Fuzz(func(t *testing.T, in []byte, pos int) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
ctx := NewTxParseContext(*u256.N1)
|
ctx := NewTxParseContext(*u256.N1, false)
|
||||||
txn := &TxSlot{}
|
txn := &TxSlot{}
|
||||||
sender := make([]byte, 20)
|
sender := make([]byte, 20)
|
||||||
_, _ = ctx.ParseTransaction(in, pos, txn, sender, false /* hasEnvelope */, true /* wrappedWithBlobs */, nil)
|
_, _ = ctx.ParseTransaction(in, pos, txn, sender, false /* hasEnvelope */, true /* wrappedWithBlobs */, nil)
|
||||||
|
1
go.mod
1
go.mod
@ -88,6 +88,7 @@ require (
|
|||||||
github.com/valyala/fastjson v1.6.4
|
github.com/valyala/fastjson v1.6.4
|
||||||
github.com/vektah/gqlparser/v2 v2.5.10
|
github.com/vektah/gqlparser/v2 v2.5.10
|
||||||
github.com/xsleonard/go-merkle v1.1.0
|
github.com/xsleonard/go-merkle v1.1.0
|
||||||
|
gitlab.com/pulsechaincom/erigon-pulse-snapshot v0.0.2
|
||||||
go.uber.org/zap v1.26.0
|
go.uber.org/zap v1.26.0
|
||||||
golang.org/x/crypto v0.17.0
|
golang.org/x/crypto v0.17.0
|
||||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9
|
golang.org/x/exp v0.0.0-20230905200255-921286631fa9
|
||||||
|
2
go.sum
2
go.sum
@ -928,6 +928,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
|||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
|
gitlab.com/pulsechaincom/erigon-pulse-snapshot v0.0.2 h1:M/ReqIKALiW5a56bdT8w9j9GZA7yqSEhO9joesRsWBQ=
|
||||||
|
gitlab.com/pulsechaincom/erigon-pulse-snapshot v0.0.2/go.mod h1:U/W4jVFkJQ1XeXul9ng2MFGYRV2bBqTxVjSEojtm18c=
|
||||||
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
|
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
|
||||||
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
|
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
|
||||||
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
|
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
|
||||||
|
@ -262,7 +262,10 @@ func makeP2PServer(
|
|||||||
protocols []p2p.Protocol,
|
protocols []p2p.Protocol,
|
||||||
) (*p2p.Server, error) {
|
) (*p2p.Server, error) {
|
||||||
var urls []string
|
var urls []string
|
||||||
chainConfig := params.ChainConfigByGenesisHash(genesisHash)
|
chainConfig := params.ChainConfigByChainName(p2pConfig.ChainName)
|
||||||
|
if chainConfig == nil {
|
||||||
|
chainConfig = params.ChainConfigByGenesisHash(genesisHash)
|
||||||
|
}
|
||||||
if chainConfig != nil {
|
if chainConfig != nil {
|
||||||
urls = params.BootnodeURLsOfChain(chainConfig.ChainName)
|
urls = params.BootnodeURLsOfChain(chainConfig.ChainName)
|
||||||
}
|
}
|
||||||
@ -990,7 +993,7 @@ func (ss *GrpcServer) SetStatus(ctx context.Context, statusData *proto_sentry.St
|
|||||||
var err error
|
var err error
|
||||||
if !ss.p2p.NoDiscovery {
|
if !ss.p2p.NoDiscovery {
|
||||||
if len(ss.discoveryDNS) == 0 {
|
if len(ss.discoveryDNS) == 0 {
|
||||||
if url := params.KnownDNSNetwork(genesisHash, "all"); url != "" {
|
if url := params.KnownDNSNetwork(genesisHash, statusData.NetworkId, "all"); url != "" {
|
||||||
ss.discoveryDNS = []string{url}
|
ss.discoveryDNS = []string{url}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,6 +173,9 @@ type Config struct {
|
|||||||
// whenever a message is sent to or received from a peer
|
// whenever a message is sent to or received from a peer
|
||||||
EnableMsgEvents bool
|
EnableMsgEvents bool
|
||||||
|
|
||||||
|
// ChainName is the name of the chain config
|
||||||
|
ChainName string `toml:",omitempty"`
|
||||||
|
|
||||||
// it is actually used but a linter got confused
|
// it is actually used but a linter got confused
|
||||||
clock mclock.Clock //nolint:structcheck
|
clock mclock.Clock //nolint:structcheck
|
||||||
|
|
||||||
|
@ -146,16 +146,42 @@ var ChiadoBootnodes = []string{
|
|||||||
"enode://595160631241ea41b187b85716f9f9572a266daa940d74edbe3b83477264ce284d69208e61cf50e91641b1b4f9a03fa8e60eb73d435a84cf4616b1c969bc2512@3.69.35.13:30303",
|
"enode://595160631241ea41b187b85716f9f9572a266daa940d74edbe3b83477264ce284d69208e61cf50e91641b1b4f9a03fa8e60eb73d435a84cf4616b1c969bc2512@3.69.35.13:30303",
|
||||||
}
|
}
|
||||||
|
|
||||||
const dnsPrefix = "enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@"
|
// PulsechainBootnodes are the enode URLs of the P2P bootstrap nodes running on
|
||||||
|
// the main Pulsechain network.
|
||||||
|
var PulsechainBootnodes = []string{
|
||||||
|
// Pulsechain Go Bootnodes
|
||||||
|
}
|
||||||
|
|
||||||
|
// PulsechainTestnetBootnodes are the enode URLs of the P2P bootstrap nodes running on
|
||||||
|
// the Pulsechain testnet network.
|
||||||
|
var PulsechainTestnetBootnodes = []string{
|
||||||
|
// Pulsechain Go Bootnodes
|
||||||
|
}
|
||||||
|
|
||||||
// KnownDNSNetwork returns the address of a public DNS-based node list for the given
|
// KnownDNSNetwork returns the address of a public DNS-based node list for the given
|
||||||
// genesis hash and protocol. See https://github.com/ethereum/discv4-dns-lists for more
|
// genesis hash and protocol. See https://github.com/ethereum/discv4-dns-lists for more
|
||||||
// information.
|
// information.
|
||||||
func KnownDNSNetwork(genesis libcommon.Hash, protocol string) string {
|
func KnownDNSNetwork(genesis libcommon.Hash, networkID uint64, protocol string) string {
|
||||||
var net string
|
var net string
|
||||||
|
var dnsPrefix = "enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@"
|
||||||
|
var tld = ".ethdisco.net"
|
||||||
|
|
||||||
|
if networkID == NetworkIDByChainName(networkname.PulsechainChainName) || networkID == NetworkIDByChainName(networkname.PulsechainTestnetChainName) {
|
||||||
|
tld = ".pulsedisco.net"
|
||||||
|
dnsPrefix = "enrtree://APFXO36RU3TWV7XFGWI2TYF5IDA3WM2GPTRL3TCZINWHZX4R6TAOK@"
|
||||||
|
}
|
||||||
|
|
||||||
switch genesis {
|
switch genesis {
|
||||||
case MainnetGenesisHash:
|
case MainnetGenesisHash:
|
||||||
|
switch networkID {
|
||||||
|
case NetworkIDByChainName(networkname.PulsechainChainName):
|
||||||
|
net = "PulseChain"
|
||||||
|
case NetworkIDByChainName(networkname.PulsechainTestnetChainName):
|
||||||
|
// TODO(bretep): Change to PulseChainTestnetV3
|
||||||
|
net = "PulseChainTestnet"
|
||||||
|
default:
|
||||||
net = "mainnet"
|
net = "mainnet"
|
||||||
|
}
|
||||||
case GoerliGenesisHash:
|
case GoerliGenesisHash:
|
||||||
net = "goerli"
|
net = "goerli"
|
||||||
case SepoliaGenesisHash:
|
case SepoliaGenesisHash:
|
||||||
@ -163,7 +189,7 @@ func KnownDNSNetwork(genesis libcommon.Hash, protocol string) string {
|
|||||||
default:
|
default:
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return dnsPrefix + protocol + "." + net + ".ethdisco.net"
|
return dnsPrefix + protocol + "." + net + tld
|
||||||
}
|
}
|
||||||
|
|
||||||
func BootnodeURLsOfChain(chain string) []string {
|
func BootnodeURLsOfChain(chain string) []string {
|
||||||
@ -186,6 +212,10 @@ func BootnodeURLsOfChain(chain string) []string {
|
|||||||
return GnosisBootnodes
|
return GnosisBootnodes
|
||||||
case networkname.ChiadoChainName:
|
case networkname.ChiadoChainName:
|
||||||
return ChiadoBootnodes
|
return ChiadoBootnodes
|
||||||
|
case networkname.PulsechainChainName:
|
||||||
|
return PulsechainBootnodes
|
||||||
|
case networkname.PulsechainTestnetChainName:
|
||||||
|
return PulsechainTestnetBootnodes
|
||||||
default:
|
default:
|
||||||
return []string{}
|
return []string{}
|
||||||
}
|
}
|
||||||
|
29
params/chainspecs/pulsechain-testnet.json
Normal file
29
params/chainspecs/pulsechain-testnet.json
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"ChainName": "pulsechain-testnet",
|
||||||
|
"chainId": 942,
|
||||||
|
"homesteadBlock": 1150000,
|
||||||
|
"daoForkBlock": 1920000,
|
||||||
|
"daoForkSupport": true,
|
||||||
|
"eip150Block": 2463000,
|
||||||
|
"eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0",
|
||||||
|
"eip155Block": 2675000,
|
||||||
|
"byzantiumBlock": 4370000,
|
||||||
|
"constantinopleBlock": 7280000,
|
||||||
|
"petersburgBlock": 7280000,
|
||||||
|
"istanbulBlock": 9069000,
|
||||||
|
"muirGlacierBlock": 9200000,
|
||||||
|
"berlinBlock": 12244000,
|
||||||
|
"londonBlock": 12965000,
|
||||||
|
"arrowGlacierBlock": 13773000,
|
||||||
|
"grayGlacierBlock": 15050000,
|
||||||
|
"terminalTotalDifficulty": 58750003716598352947541,
|
||||||
|
"terminalTotalDifficultyPassed": true,
|
||||||
|
"ethash": {},
|
||||||
|
"primordialPulseBlock": 15669697,
|
||||||
|
"pulseChain": {
|
||||||
|
"treasury": {
|
||||||
|
"addr": "0xceB59257450820132aB274ED61C49E5FD96E8868",
|
||||||
|
"balance": "0xc9f2c9cd04674edea40000000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
params/chainspecs/pulsechain.json
Normal file
24
params/chainspecs/pulsechain.json
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"ChainName": "pulsechain",
|
||||||
|
"chainId": 369,
|
||||||
|
"homesteadBlock": 1150000,
|
||||||
|
"daoForkBlock": 1920000,
|
||||||
|
"daoForkSupport": true,
|
||||||
|
"eip150Block": 2463000,
|
||||||
|
"eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0",
|
||||||
|
"eip155Block": 2675000,
|
||||||
|
"byzantiumBlock": 4370000,
|
||||||
|
"constantinopleBlock": 7280000,
|
||||||
|
"petersburgBlock": 7280000,
|
||||||
|
"istanbulBlock": 9069000,
|
||||||
|
"muirGlacierBlock": 9200000,
|
||||||
|
"berlinBlock": 12244000,
|
||||||
|
"londonBlock": 12965000,
|
||||||
|
"arrowGlacierBlock": 13773000,
|
||||||
|
"grayGlacierBlock": 15050000,
|
||||||
|
"terminalTotalDifficulty": 58750003716598352947541,
|
||||||
|
"terminalTotalDifficultyPassed": true,
|
||||||
|
"ethash": {},
|
||||||
|
"primordialPulseBlock": 15669697,
|
||||||
|
"pulseChain": {}
|
||||||
|
}
|
@ -72,6 +72,8 @@ var (
|
|||||||
BorDevnetGenesisHash = libcommon.HexToHash("0x5a06b25b0c6530708ea0b98a3409290e39dce6be7f558493aeb6e4b99a172a87")
|
BorDevnetGenesisHash = libcommon.HexToHash("0x5a06b25b0c6530708ea0b98a3409290e39dce6be7f558493aeb6e4b99a172a87")
|
||||||
GnosisGenesisHash = libcommon.HexToHash("0x4f1dd23188aab3a76b463e4af801b52b1248ef073c648cbdc4c9333d3da79756")
|
GnosisGenesisHash = libcommon.HexToHash("0x4f1dd23188aab3a76b463e4af801b52b1248ef073c648cbdc4c9333d3da79756")
|
||||||
ChiadoGenesisHash = libcommon.HexToHash("0xada44fd8d2ecab8b08f256af07ad3e777f17fb434f8f8e678b312f576212ba9a")
|
ChiadoGenesisHash = libcommon.HexToHash("0xada44fd8d2ecab8b08f256af07ad3e777f17fb434f8f8e678b312f576212ba9a")
|
||||||
|
PulsechainGenesisHash = libcommon.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
|
||||||
|
PulsechainTetnetGenesisHash = libcommon.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -114,6 +116,8 @@ var (
|
|||||||
ShanghaiTime: big.NewInt(0),
|
ShanghaiTime: big.NewInt(0),
|
||||||
CancunTime: big.NewInt(0),
|
CancunTime: big.NewInt(0),
|
||||||
Ethash: new(chain.EthashConfig),
|
Ethash: new(chain.EthashConfig),
|
||||||
|
PrimordialPulseBlock: nil,
|
||||||
|
PulseChain: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
|
// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
|
||||||
@ -146,6 +150,10 @@ var (
|
|||||||
|
|
||||||
ChiadoChainConfig = readChainSpec("chainspecs/chiado.json")
|
ChiadoChainConfig = readChainSpec("chainspecs/chiado.json")
|
||||||
|
|
||||||
|
PulsechainChainConfig = readChainSpec("chainspecs/pulsechain.json")
|
||||||
|
|
||||||
|
PulsechainTestnetChainConfig = readChainSpec("chainspecs/pulsechain-testnet.json")
|
||||||
|
|
||||||
CliqueSnapshot = NewSnapshotConfig(10, 1024, 16384, true, "")
|
CliqueSnapshot = NewSnapshotConfig(10, 1024, 16384, true, "")
|
||||||
|
|
||||||
TestChainConfig = &chain.Config{
|
TestChainConfig = &chain.Config{
|
||||||
@ -161,6 +169,8 @@ var (
|
|||||||
MuirGlacierBlock: big.NewInt(0),
|
MuirGlacierBlock: big.NewInt(0),
|
||||||
BerlinBlock: big.NewInt(0),
|
BerlinBlock: big.NewInt(0),
|
||||||
Ethash: new(chain.EthashConfig),
|
Ethash: new(chain.EthashConfig),
|
||||||
|
PrimordialPulseBlock: nil,
|
||||||
|
PulseChain: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
TestChainAuraConfig = &chain.Config{
|
TestChainAuraConfig = &chain.Config{
|
||||||
@ -230,6 +240,10 @@ func ChainConfigByChainName(chain string) *chain.Config {
|
|||||||
return GnosisChainConfig
|
return GnosisChainConfig
|
||||||
case networkname.ChiadoChainName:
|
case networkname.ChiadoChainName:
|
||||||
return ChiadoChainConfig
|
return ChiadoChainConfig
|
||||||
|
case networkname.PulsechainChainName:
|
||||||
|
return PulsechainChainConfig
|
||||||
|
case networkname.PulsechainTestnetChainName:
|
||||||
|
return PulsechainTestnetChainConfig
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -257,6 +271,10 @@ func GenesisHashByChainName(chain string) *libcommon.Hash {
|
|||||||
return &GnosisGenesisHash
|
return &GnosisGenesisHash
|
||||||
case networkname.ChiadoChainName:
|
case networkname.ChiadoChainName:
|
||||||
return &ChiadoGenesisHash
|
return &ChiadoGenesisHash
|
||||||
|
case networkname.PulsechainChainName:
|
||||||
|
return &PulsechainGenesisHash
|
||||||
|
case networkname.PulsechainTestnetChainName:
|
||||||
|
return &PulsechainTetnetGenesisHash
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
78
pulse/deposit_contract.go
Normal file
78
pulse/deposit_contract.go
Normal file
File diff suppressed because one or more lines are too long
13
pulse/pulse.go
Normal file
13
pulse/pulse.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Package pulse implements the PulseChain fork.
|
||||||
|
package pulse
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ledgerwatch/erigon-lib/chain"
|
||||||
|
"github.com/ledgerwatch/erigon/core/state"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PrimordialPulseFork applies the PrimordialPulse fork changes.
|
||||||
|
func PrimordialPulseFork(state *state.IntraBlockState, pulseChainConfig *chain.PulseChainConfig) {
|
||||||
|
applySacrificeCredits(state, pulseChainConfig)
|
||||||
|
replaceDepositContract(state)
|
||||||
|
}
|
BIN
pulse/sacrifice_credits.bin
Normal file
BIN
pulse/sacrifice_credits.bin
Normal file
Binary file not shown.
56
pulse/sacrifice_credits.go
Normal file
56
pulse/sacrifice_credits.go
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package pulse
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "embed"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/holiman/uint256"
|
||||||
|
"github.com/ledgerwatch/erigon-lib/chain"
|
||||||
|
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
||||||
|
"github.com/ledgerwatch/log/v3"
|
||||||
|
|
||||||
|
"github.com/ledgerwatch/erigon/core/state"
|
||||||
|
)
|
||||||
|
|
||||||
|
// The testnet credits are approximate and not final for mainnet
|
||||||
|
// see https://gitlab.com/pulsechaincom/compressed-allocations/-/tree/Testnet-R2-Credits
|
||||||
|
//
|
||||||
|
//go:embed sacrifice_credits.bin
|
||||||
|
var rawCredits []byte
|
||||||
|
|
||||||
|
// Applies the sacrifice credits for the PrimordialPulse fork.
|
||||||
|
func applySacrificeCredits(state *state.IntraBlockState, pulseChainConfig *chain.PulseChainConfig) {
|
||||||
|
if pulseChainConfig != nil && pulseChainConfig.Treasury != nil {
|
||||||
|
balance, err := uint256.FromHex(pulseChainConfig.Treasury.Balance)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
log.Info("Applying PrimordialPulse treasury allocation 💸")
|
||||||
|
log.Info(fmt.Sprintf("Applying PrimordialPulse treasury allocation address: %s", libcommon.HexToAddress(pulseChainConfig.Treasury.Addr).String()))
|
||||||
|
log.Info(fmt.Sprintf("Applying PrimordialPulse treasury allocation amount: %d", balance))
|
||||||
|
state.AddBalance(libcommon.HexToAddress(pulseChainConfig.Treasury.Addr), balance)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("Applying PrimordialPulse sacrifice credits 💸")
|
||||||
|
for ptr := 0; ptr < len(rawCredits); {
|
||||||
|
byteCount := int(rawCredits[ptr])
|
||||||
|
ptr++
|
||||||
|
|
||||||
|
record := rawCredits[ptr : ptr+byteCount]
|
||||||
|
ptr += byteCount
|
||||||
|
|
||||||
|
addr := libcommon.BytesToAddress(record[:20])
|
||||||
|
hexBalance := hex.EncodeToString(record[20:])
|
||||||
|
credit, err := uint256.FromHex("0x" + strings.TrimLeft(hexBalance, "0"))
|
||||||
|
if err != nil {
|
||||||
|
log.Info(fmt.Sprintf("Applying PrimordialPulse sacrifice credits amount: %s", hexBalance))
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
state.AddBalance(addr, credit)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("Finished applying PrimordialPulse sacrifice credits 🤑")
|
||||||
|
}
|
@ -84,6 +84,10 @@ func NewNodConfigUrfave(ctx *cli.Context, logger log.Logger) *nodecfg.Config {
|
|||||||
logger.Info("Starting Erigon on Bor Mainnet...")
|
logger.Info("Starting Erigon on Bor Mainnet...")
|
||||||
case networkname.BorDevnetChainName:
|
case networkname.BorDevnetChainName:
|
||||||
logger.Info("Starting Erigon on Bor Devnet...")
|
logger.Info("Starting Erigon on Bor Devnet...")
|
||||||
|
case networkname.PulsechainChainName:
|
||||||
|
logger.Info("Starting Erigon on PulseChain...")
|
||||||
|
case networkname.PulsechainTestnetChainName:
|
||||||
|
logger.Info("Starting Erigon on PulseChain Testnet...")
|
||||||
case "", networkname.MainnetChainName:
|
case "", networkname.MainnetChainName:
|
||||||
if !ctx.IsSet(utils.NetworkIdFlag.Name) {
|
if !ctx.IsSet(utils.NetworkIdFlag.Name) {
|
||||||
logger.Info("Starting Erigon on Ethereum mainnet...")
|
logger.Info("Starting Erigon on Ethereum mainnet...")
|
||||||
|
@ -1796,6 +1796,7 @@ func DumpTxs(ctx context.Context, db kv.RoDB, blockFrom, blockTo uint64, chainCo
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
chainID, _ := uint256.FromBig(chainConfig.ChainID)
|
chainID, _ := uint256.FromBig(chainConfig.ChainID)
|
||||||
|
isPulseChain := chainConfig.PulseChain != nil
|
||||||
|
|
||||||
numBuf := make([]byte, 8)
|
numBuf := make([]byte, 8)
|
||||||
|
|
||||||
@ -1904,7 +1905,7 @@ func DumpTxs(ctx context.Context, db kv.RoDB, blockFrom, blockTo uint64, chainCo
|
|||||||
valueBuf := bufPool.Get().([]byte)
|
valueBuf := bufPool.Get().([]byte)
|
||||||
defer bufPool.Put(valueBuf) //nolint
|
defer bufPool.Put(valueBuf) //nolint
|
||||||
valueBufs[i] = valueBuf
|
valueBufs[i] = valueBuf
|
||||||
parseCtxs[i] = types2.NewTxParseContext(*chainID)
|
parseCtxs[i] = types2.NewTxParseContext(*chainID, isPulseChain)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := addSystemTx(parseCtxs[0], tx, body.BaseTxId); err != nil {
|
if err := addSystemTx(parseCtxs[0], tx, body.BaseTxId); err != nil {
|
||||||
@ -2205,8 +2206,8 @@ func TransactionsIdx(ctx context.Context, chainConfig *chain.Config, version uin
|
|||||||
txnHash2BlockNumIdx.LogLvl(log.LvlDebug)
|
txnHash2BlockNumIdx.LogLvl(log.LvlDebug)
|
||||||
|
|
||||||
chainId, _ := uint256.FromBig(chainConfig.ChainID)
|
chainId, _ := uint256.FromBig(chainConfig.ChainID)
|
||||||
|
isPulseChain := chainConfig.PulseChain != nil
|
||||||
parseCtx := types2.NewTxParseContext(*chainId)
|
parseCtx := types2.NewTxParseContext(*chainId, isPulseChain)
|
||||||
parseCtx.WithSender(false)
|
parseCtx.WithSender(false)
|
||||||
slot := types2.TxSlot{}
|
slot := types2.TxSlot{}
|
||||||
bodyBuf, word := make([]byte, 0, 4096), make([]byte, 0, 4096)
|
bodyBuf, word := make([]byte, 0, 4096), make([]byte, 0, 4096)
|
||||||
|
@ -101,7 +101,7 @@ func TestDump(t *testing.T) {
|
|||||||
t.Run("txs", func(t *testing.T) {
|
t.Run("txs", func(t *testing.T) {
|
||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
slot := types2.TxSlot{}
|
slot := types2.TxSlot{}
|
||||||
parseCtx := types2.NewTxParseContext(*chainID)
|
parseCtx := types2.NewTxParseContext(*chainID, false)
|
||||||
parseCtx.WithSender(false)
|
parseCtx.WithSender(false)
|
||||||
var sender [20]byte
|
var sender [20]byte
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ func TestDump(t *testing.T) {
|
|||||||
t.Run("txs_not_from_zero", func(t *testing.T) {
|
t.Run("txs_not_from_zero", func(t *testing.T) {
|
||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
slot := types2.TxSlot{}
|
slot := types2.TxSlot{}
|
||||||
parseCtx := types2.NewTxParseContext(*chainID)
|
parseCtx := types2.NewTxParseContext(*chainID, false)
|
||||||
parseCtx.WithSender(false)
|
parseCtx.WithSender(false)
|
||||||
var sender [20]byte
|
var sender [20]byte
|
||||||
|
|
||||||
|
@ -609,7 +609,7 @@ func (hd *HeaderDownload) InsertHeader(hf FeedHeaderFunc, terminalTotalDifficult
|
|||||||
link.ClearChildren()
|
link.ClearChildren()
|
||||||
}
|
}
|
||||||
var blocksToTTD uint64
|
var blocksToTTD uint64
|
||||||
if terminalTotalDifficulty != nil && returnTd != nil && lastD != nil {
|
if terminalTotalDifficulty != nil && returnTd != nil && lastD != nil && lastD.Uint64() != 0 {
|
||||||
// Calculate the estimation of when TTD will be hit
|
// Calculate the estimation of when TTD will be hit
|
||||||
var x big.Int
|
var x big.Int
|
||||||
x.Sub(terminalTotalDifficulty, returnTd)
|
x.Sub(terminalTotalDifficulty, returnTd)
|
||||||
|
Loading…
Reference in New Issue
Block a user