mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 13:21:37 +00:00
parent
50210d90e3
commit
cc2109342c
11 changed files with 323 additions and 8 deletions
|
|
@ -16,7 +16,11 @@
|
|||
|
||||
package common
|
||||
|
||||
import "math/big"
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
// Common big integers often used
|
||||
var (
|
||||
|
|
@ -27,4 +31,6 @@ var (
|
|||
Big32 = big.NewInt(32)
|
||||
Big256 = big.NewInt(256)
|
||||
Big257 = big.NewInt(257)
|
||||
|
||||
U2560 = uint256.NewInt(0)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ func (b *BlockGen) OffsetTime(seconds int64) {
|
|||
if b.header.Time <= b.parent.Header().Time {
|
||||
panic("block time out of range")
|
||||
}
|
||||
chainReader := &fakeChainReader{config: b.config}
|
||||
chainReader := &fakeChainReader{config: b.config, engine: b.engine}
|
||||
b.header.Difficulty = b.engine.CalcDifficulty(chainReader, b.header.Time, b.parent.Header())
|
||||
}
|
||||
|
||||
|
|
@ -214,7 +214,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
|
|||
config = params.TestChainConfig
|
||||
}
|
||||
blocks, receipts := make(types.Blocks, n), make([]types.Receipts, n)
|
||||
chainReader := &fakeChainReader{config: config}
|
||||
chainReader := &fakeChainReader{config: config, engine: engine}
|
||||
genblock := func(i int, parent *types.Block, statedb *state.StateDB) (*types.Block, types.Receipts) {
|
||||
b := &BlockGen{i: i, parent: parent, chain: blocks, statedb: statedb, config: config, engine: engine}
|
||||
b.header = makeHeader(chainReader, parent, statedb, b.engine)
|
||||
|
|
@ -231,10 +231,19 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
|
|||
if config.DAOForkSupport && config.DAOForkBlock != nil && config.DAOForkBlock.Cmp(b.header.Number) == 0 {
|
||||
misc.ApplyDAOHardFork(statedb)
|
||||
}
|
||||
// Execute any user modifications to the block and finalize it
|
||||
|
||||
if config.IsPrague(b.header.Number) {
|
||||
// EIP-2935
|
||||
blockContext := NewEVMBlockContext(b.header, chainReader, &b.header.Coinbase)
|
||||
evm := vm.NewEVM(blockContext, vm.TxContext{}, statedb, nil, config, vm.Config{})
|
||||
ProcessParentBlockHash(b.header.ParentHash, evm, statedb)
|
||||
}
|
||||
|
||||
// Execute any user modifications to the block
|
||||
if gen != nil {
|
||||
gen(i, b)
|
||||
}
|
||||
|
||||
if b.engine != nil {
|
||||
// Finalize and seal the block
|
||||
block, _ := b.engine.Finalize(chainReader, b.header, statedb, statedb.Copy(), b.txs, b.uncles, b.receipts)
|
||||
|
|
@ -323,6 +332,7 @@ func makeBlockChain(parent *types.Block, n int, engine consensus.Engine, db ethd
|
|||
|
||||
type fakeChainReader struct {
|
||||
config *params.ChainConfig
|
||||
engine consensus.Engine
|
||||
}
|
||||
|
||||
// Config returns the chain configuration.
|
||||
|
|
@ -330,6 +340,7 @@ func (cr *fakeChainReader) Config() *params.ChainConfig {
|
|||
return cr.config
|
||||
}
|
||||
|
||||
func (cr *fakeChainReader) Engine() consensus.Engine { return cr.engine }
|
||||
func (cr *fakeChainReader) CurrentHeader() *types.Header { return nil }
|
||||
func (cr *fakeChainReader) GetHeaderByNumber(number uint64) *types.Header { return nil }
|
||||
func (cr *fakeChainReader) GetHeaderByHash(hash common.Hash) *types.Header { return nil }
|
||||
|
|
|
|||
|
|
@ -465,8 +465,7 @@ func DefaultDevnetGenesisBlock() *Genesis {
|
|||
}
|
||||
}
|
||||
|
||||
// DeveloperGenesisBlock returns the 'geth --dev' genesis block. Note, this must
|
||||
// be seeded with the
|
||||
// DeveloperGenesisBlock returns the 'geth --dev' genesis block.
|
||||
func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis {
|
||||
// Override the default period to the user requested one
|
||||
config := *params.AllXDPoSProtocolChanges
|
||||
|
|
@ -489,6 +488,8 @@ func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis {
|
|||
common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul
|
||||
common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing
|
||||
faucet: {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))},
|
||||
// Pre-deploy system contracts
|
||||
params.HistoryStorageAddress: {Nonce: 1, Code: params.HistoryStorageCode, Balance: common.Big0},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"runtime"
|
||||
|
|
@ -100,6 +102,10 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, tra
|
|||
signer := types.MakeSigner(p.config, blockNumber)
|
||||
coinbaseOwner := getCoinbaseOwner(p.bc, statedb, header, nil)
|
||||
|
||||
if p.config.IsPrague(block.Number()) {
|
||||
ProcessParentBlockHash(block.ParentHash(), vmenv, tracingStateDB)
|
||||
}
|
||||
|
||||
// Iterate over and process the individual transactions
|
||||
for i, tx := range block.Transactions() {
|
||||
// check denylist txs after hf
|
||||
|
|
@ -203,6 +209,10 @@ func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, stated
|
|||
signer := types.MakeSigner(p.config, blockNumber)
|
||||
coinbaseOwner := getCoinbaseOwner(p.bc, statedb, header, nil)
|
||||
|
||||
if p.config.IsPrague(block.Number()) {
|
||||
ProcessParentBlockHash(block.ParentHash(), vmenv, tracingStateDB)
|
||||
}
|
||||
|
||||
// Iterate over and process the individual transactions
|
||||
receipts = make([]*types.Receipt, block.Transactions().Len())
|
||||
for i, tx := range block.Transactions() {
|
||||
|
|
@ -639,3 +649,95 @@ func InitSignerInTransactions(config *params.ChainConfig, header *types.Header,
|
|||
}
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
// ProcessParentBlockHash writes the parent hash to the EIP-2935 history contract
|
||||
// and enforces the expected code, with a one-time Prague backfill if missing.
|
||||
func ProcessParentBlockHash(prevHash common.Hash, vmenv *vm.EVM, statedb vm.StateDB) {
|
||||
// Verify history contract code matches the expected bytecode
|
||||
code := statedb.GetCode(params.HistoryStorageAddress)
|
||||
if len(code) > 0 && !bytes.Equal(code, params.HistoryStorageCode) {
|
||||
log.Error("History storage code mismatch",
|
||||
"have", crypto.Keccak256Hash(code),
|
||||
"want", crypto.Keccak256Hash(params.HistoryStorageCode),
|
||||
)
|
||||
panic("history storage code mismatch")
|
||||
}
|
||||
|
||||
blockNumber := vmenv.Context.BlockNumber
|
||||
if blockNumber == nil || !vmenv.ChainConfig().IsPrague(blockNumber) {
|
||||
return
|
||||
}
|
||||
forkBlock := vmenv.ChainConfig().PragueBlock
|
||||
if forkBlock == nil {
|
||||
forkBlock = common.PragueBlock
|
||||
}
|
||||
if forkBlock == nil || blockNumber.Cmp(forkBlock) < 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Only deploy and backfill if the contract is missing at/after Prague activation.
|
||||
if len(code) == 0 {
|
||||
if !statedb.Exist(params.HistoryStorageAddress) {
|
||||
statedb.CreateAccount(params.HistoryStorageAddress)
|
||||
}
|
||||
if statedb.GetNonce(params.HistoryStorageAddress) == 0 {
|
||||
statedb.SetNonce(params.HistoryStorageAddress, 1)
|
||||
}
|
||||
statedb.SetCode(params.HistoryStorageAddress, params.HistoryStorageCode)
|
||||
|
||||
if blockNumber.Sign() > 0 {
|
||||
end := blockNumber.Uint64() - 1
|
||||
start := end
|
||||
if end+1 > params.HistoryServeWindow {
|
||||
start = end + 1 - params.HistoryServeWindow
|
||||
}
|
||||
if forkBlock.Sign() > 0 {
|
||||
forkStart := forkBlock.Uint64() - 1
|
||||
if forkStart > start {
|
||||
start = forkStart
|
||||
}
|
||||
}
|
||||
for n := start; n <= end; n++ {
|
||||
hash := vmenv.Context.GetHash(n)
|
||||
if hash == (common.Hash{}) {
|
||||
log.Debug("History backfill missing hash", "number", n)
|
||||
continue
|
||||
}
|
||||
statedb.SetState(params.HistoryStorageAddress, historyStorageKey(n), hash)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if tracer := vmenv.Config.Tracer; tracer != nil {
|
||||
if tracer.OnSystemCallStart != nil {
|
||||
tracer.OnSystemCallStart()
|
||||
}
|
||||
if tracer.OnSystemCallEnd != nil {
|
||||
defer tracer.OnSystemCallEnd()
|
||||
}
|
||||
}
|
||||
|
||||
msg := &Message{
|
||||
From: params.SystemAddress,
|
||||
GasLimit: 30_000_000,
|
||||
GasPrice: common.Big0,
|
||||
GasFeeCap: common.Big0,
|
||||
GasTipCap: common.Big0,
|
||||
To: ¶ms.HistoryStorageAddress,
|
||||
Data: prevHash.Bytes(),
|
||||
}
|
||||
vmenv.Reset(NewEVMTxContext(msg), statedb)
|
||||
statedb.AddAddressToAccessList(params.HistoryStorageAddress)
|
||||
_, _, err := vmenv.Call(vm.AccountRef(msg.From), *msg.To, msg.Data, 30_000_000, common.U2560)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
statedb.Finalise(true)
|
||||
}
|
||||
|
||||
func historyStorageKey(number uint64) common.Hash {
|
||||
ringIndex := number % params.HistoryServeWindow
|
||||
var key common.Hash
|
||||
binary.BigEndian.PutUint64(key[24:], ringIndex)
|
||||
return key
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package core
|
|||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"encoding/binary"
|
||||
"math"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
|
@ -26,10 +27,12 @@ import (
|
|||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||
"github.com/XinFinOrg/XDPoSChain/consensus/ethash"
|
||||
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
|
||||
"github.com/XinFinOrg/XDPoSChain/core/state"
|
||||
"github.com/XinFinOrg/XDPoSChain/core/tracing"
|
||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||
"github.com/XinFinOrg/XDPoSChain/core/vm"
|
||||
"github.com/XinFinOrg/XDPoSChain/crypto"
|
||||
"github.com/XinFinOrg/XDPoSChain/ethdb/memorydb"
|
||||
"github.com/XinFinOrg/XDPoSChain/params"
|
||||
"github.com/XinFinOrg/XDPoSChain/trie"
|
||||
"github.com/holiman/uint256"
|
||||
|
|
@ -318,7 +321,7 @@ func GenerateBadBlock(t *testing.T, parent *types.Block, engine consensus.Engine
|
|||
header := &types.Header{
|
||||
ParentHash: parent.Hash(),
|
||||
Coinbase: parent.Coinbase(),
|
||||
Difficulty: engine.CalcDifficulty(&fakeChainReader{config}, parent.Time()+10, &types.Header{
|
||||
Difficulty: engine.CalcDifficulty(&fakeChainReader{config: config, engine: engine}, parent.Time()+10, &types.Header{
|
||||
Number: parent.Number(),
|
||||
Time: parent.Time(),
|
||||
Difficulty: parent.Difficulty(),
|
||||
|
|
@ -489,3 +492,146 @@ func TestApplyTransactionWithEVMTracer(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessParentBlockHash(t *testing.T) {
|
||||
var (
|
||||
chainConfig = params.MergedTestChainConfig
|
||||
hashA = common.Hash{0x01}
|
||||
hashB = common.Hash{0x02}
|
||||
header = &types.Header{ParentHash: hashA, Number: big.NewInt(2), Difficulty: big.NewInt(0)}
|
||||
parent = &types.Header{ParentHash: hashB, Number: big.NewInt(1), Difficulty: big.NewInt(0)}
|
||||
coinbase = common.Address{}
|
||||
)
|
||||
test := func(statedb *state.StateDB) {
|
||||
statedb.SetNonce(params.HistoryStorageAddress, 1)
|
||||
statedb.SetCode(params.HistoryStorageAddress, params.HistoryStorageCode)
|
||||
statedb.IntermediateRoot(true)
|
||||
|
||||
vmContext := NewEVMBlockContext(header, nil, &coinbase)
|
||||
evm := vm.NewEVM(vmContext, vm.TxContext{}, statedb, nil, chainConfig, vm.Config{})
|
||||
ProcessParentBlockHash(header.ParentHash, evm, statedb)
|
||||
|
||||
vmContext = NewEVMBlockContext(parent, nil, &coinbase)
|
||||
evm = vm.NewEVM(vmContext, vm.TxContext{}, statedb, nil, chainConfig, vm.Config{})
|
||||
ProcessParentBlockHash(parent.ParentHash, evm, statedb)
|
||||
|
||||
// make sure that the state is correct
|
||||
if have := getParentBlockHash(statedb, 1); have != hashA {
|
||||
t.Errorf("want parent hash %v, have %v", hashA, have)
|
||||
}
|
||||
if have := getParentBlockHash(statedb, 0); have != hashB {
|
||||
t.Errorf("want parent hash %v, have %v", hashB, have)
|
||||
}
|
||||
}
|
||||
t.Run("MPT", func(t *testing.T) {
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewDatabase(memorydb.New())))
|
||||
test(statedb)
|
||||
})
|
||||
}
|
||||
|
||||
func TestProcessParentBlockHashPragueGuard(t *testing.T) {
|
||||
config := *params.MergedTestChainConfig
|
||||
config.PragueBlock = big.NewInt(10)
|
||||
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewDatabase(memorydb.New())))
|
||||
blockNumber := big.NewInt(5)
|
||||
random := common.Hash{}
|
||||
blockContext := vm.BlockContext{
|
||||
CanTransfer: CanTransfer,
|
||||
Transfer: Transfer,
|
||||
GetHash: func(uint64) common.Hash { return common.Hash{} },
|
||||
Coinbase: common.Address{},
|
||||
BlockNumber: blockNumber,
|
||||
Time: 0,
|
||||
Difficulty: big.NewInt(0),
|
||||
GasLimit: 0,
|
||||
BaseFee: nil,
|
||||
Random: &random,
|
||||
}
|
||||
evmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, nil, &config, vm.Config{})
|
||||
ProcessParentBlockHash(common.Hash{0x01}, evmenv, statedb)
|
||||
|
||||
if code := statedb.GetCode(params.HistoryStorageAddress); len(code) != 0 {
|
||||
t.Fatalf("unexpected history contract code predeploy: %x", code)
|
||||
}
|
||||
if have := getParentBlockHash(statedb, 0); have != (common.Hash{}) {
|
||||
t.Fatalf("expected empty history slot, have %v", have)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessParentBlockHashBackfillMissingHistory(t *testing.T) {
|
||||
config := *params.MergedTestChainConfig
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewDatabase(memorydb.New())))
|
||||
blockNumber := big.NewInt(int64(params.HistoryServeWindow + 1))
|
||||
available := map[uint64]common.Hash{
|
||||
1: {0x11},
|
||||
100: {0x22},
|
||||
}
|
||||
|
||||
random := common.Hash{}
|
||||
blockContext := vm.BlockContext{
|
||||
CanTransfer: CanTransfer,
|
||||
Transfer: Transfer,
|
||||
GetHash: func(n uint64) common.Hash {
|
||||
if hash, ok := available[n]; ok {
|
||||
return hash
|
||||
}
|
||||
return common.Hash{}
|
||||
},
|
||||
Coinbase: common.Address{},
|
||||
BlockNumber: blockNumber,
|
||||
Time: 0,
|
||||
Difficulty: big.NewInt(0),
|
||||
GasLimit: 0,
|
||||
BaseFee: nil,
|
||||
Random: &random,
|
||||
}
|
||||
evmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, nil, &config, vm.Config{})
|
||||
ProcessParentBlockHash(common.Hash{0x01}, evmenv, statedb)
|
||||
|
||||
if have := getParentBlockHash(statedb, 1); have != available[1] {
|
||||
t.Fatalf("expected hash at slot 1, have %v", have)
|
||||
}
|
||||
if have := getParentBlockHash(statedb, 100); have != available[100] {
|
||||
t.Fatalf("expected hash at slot 100, have %v", have)
|
||||
}
|
||||
if have := getParentBlockHash(statedb, 2); have != (common.Hash{}) {
|
||||
t.Fatalf("expected empty history slot, have %v", have)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessParentBlockHashCodeMismatchPanics(t *testing.T) {
|
||||
config := *params.MergedTestChainConfig
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewDatabase(memorydb.New())))
|
||||
statedb.SetCode(params.HistoryStorageAddress, []byte{0x01})
|
||||
|
||||
blockNumber := big.NewInt(1)
|
||||
random := common.Hash{}
|
||||
blockContext := vm.BlockContext{
|
||||
CanTransfer: CanTransfer,
|
||||
Transfer: Transfer,
|
||||
GetHash: func(uint64) common.Hash { return common.Hash{} },
|
||||
Coinbase: common.Address{},
|
||||
BlockNumber: blockNumber,
|
||||
Time: 0,
|
||||
Difficulty: big.NewInt(0),
|
||||
GasLimit: 0,
|
||||
BaseFee: nil,
|
||||
Random: &random,
|
||||
}
|
||||
evmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, nil, &config, vm.Config{})
|
||||
|
||||
defer func() {
|
||||
if recover() == nil {
|
||||
t.Fatal("expected panic on history storage code mismatch")
|
||||
}
|
||||
}()
|
||||
ProcessParentBlockHash(common.Hash{0x01}, evmenv, statedb)
|
||||
}
|
||||
|
||||
func getParentBlockHash(statedb *state.StateDB, number uint64) common.Hash {
|
||||
ringIndex := number % params.HistoryServeWindow
|
||||
var key common.Hash
|
||||
binary.BigEndian.PutUint64(key[24:], ringIndex)
|
||||
return statedb.GetState(params.HistoryStorageAddress, key)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,3 +4,4 @@
|
|||
- [Validator Contract](xdc/validator.md)
|
||||
- [Development environment](develop.md)
|
||||
- [Solidity](solidity.md)
|
||||
- [Upgrade notes](upgrade.md)
|
||||
|
|
|
|||
8
docs/upgrade.md
Normal file
8
docs/upgrade.md
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# Upgrade Notes
|
||||
|
||||
## Prague / EIP-2935
|
||||
|
||||
- The history storage contract is predeployed only in the developer genesis.
|
||||
- For other networks, the contract is deployed at Prague activation by the system call during block processing and state access.
|
||||
- Nodes upgrading after Prague will perform a one-time backfill of recent parent hashes into the ring buffer. If historical headers are pruned or unavailable, missing slots are skipped and only available hashes are filled.
|
||||
- If you maintain a custom genesis and want predeployment, add an account entry for `HistoryStorageAddress` with `Nonce: 1` and `Code: HistoryStorageCode`.
|
||||
|
|
@ -206,6 +206,12 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
|
|||
if err != nil {
|
||||
return nil, vm.BlockContext{}, nil, nil, err
|
||||
}
|
||||
// If prague hardfork, insert parent block hash in the state as per EIP-2935.
|
||||
if eth.blockchain.Config().IsPrague(block.Number()) {
|
||||
context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil)
|
||||
vmenv := vm.NewEVM(context, vm.TxContext{}, statedb, nil, eth.blockchain.Config(), vm.Config{})
|
||||
core.ProcessParentBlockHash(block.ParentHash(), vmenv, statedb)
|
||||
}
|
||||
if txIndex == 0 && len(block.Transactions()) == 0 {
|
||||
return nil, vm.BlockContext{}, statedb, release, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -379,6 +379,12 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
|
|||
failed = err
|
||||
break
|
||||
}
|
||||
// Insert parent hash in history contract.
|
||||
if api.backend.ChainConfig().IsPrague(next.Number()) {
|
||||
context := core.NewEVMBlockContext(next.Header(), api.chainContext(ctx), nil)
|
||||
vmenv := vm.NewEVM(context, vm.TxContext{}, statedb, nil, api.backend.ChainConfig(), vm.Config{})
|
||||
core.ProcessParentBlockHash(next.ParentHash(), vmenv, statedb)
|
||||
}
|
||||
// Clean out any pending release functions of trace state. Note this
|
||||
// step must be done after constructing tracing state, because the
|
||||
// tracing state of block next depends on the parent state and construction
|
||||
|
|
@ -513,6 +519,9 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config
|
|||
vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
||||
deleteEmptyObjects = chainConfig.IsEIP158(block.Number())
|
||||
)
|
||||
if chainConfig.IsPrague(block.Number()) {
|
||||
core.ProcessParentBlockHash(block.ParentHash(), vm.NewEVM(vmctx, vm.TxContext{}, statedb, nil, chainConfig, vm.Config{}), statedb)
|
||||
}
|
||||
feeCapacity := statedb.GetTRC21FeeCapacityFromState()
|
||||
for i, tx := range block.Transactions() {
|
||||
if err := ctx.Err(); err != nil {
|
||||
|
|
@ -593,6 +602,10 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
|
|||
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number())
|
||||
results = make([]*txTraceResult, len(txs))
|
||||
)
|
||||
if api.backend.ChainConfig().IsPrague(block.Number()) {
|
||||
vmenv := vm.NewEVM(blockCtx, vm.TxContext{}, statedb, nil, api.backend.ChainConfig(), vm.Config{})
|
||||
core.ProcessParentBlockHash(block.ParentHash(), vmenv, statedb)
|
||||
}
|
||||
feeCapacity := statedb.GetTRC21FeeCapacityFromState()
|
||||
for i, tx := range txs {
|
||||
var balance *big.Int
|
||||
|
|
|
|||
|
|
@ -787,6 +787,11 @@ func (w *worker) commitNewWork() {
|
|||
if common.TIPSigning.Cmp(header.Number) == 0 {
|
||||
work.state.DeleteAddress(common.BlockSignersBinary)
|
||||
}
|
||||
if w.config.IsPrague(header.Number) {
|
||||
context := core.NewEVMBlockContext(header, w.chain, nil)
|
||||
vmenv := vm.NewEVM(context, vm.TxContext{}, w.current.state, nil, w.config, vm.Config{})
|
||||
core.ProcessParentBlockHash(header.ParentHash, vmenv, w.current.state)
|
||||
}
|
||||
// won't grasp txs at checkpoint
|
||||
var (
|
||||
txs *transactionsByPriceAndNonce
|
||||
|
|
|
|||
|
|
@ -16,7 +16,11 @@
|
|||
|
||||
package params
|
||||
|
||||
import "math/big"
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/common"
|
||||
)
|
||||
|
||||
const (
|
||||
GasLimitBoundDivisor uint64 = 1024 // The bound divisor of the gas limit, used in update calculations.
|
||||
|
|
@ -160,6 +164,8 @@ const (
|
|||
Bn256PairingBaseGasIstanbul uint64 = 45000 // Base price for an elliptic curve pairing check
|
||||
Bn256PairingPerPointGasByzantium uint64 = 80000 // Byzantium per-point price for an elliptic curve pairing check
|
||||
Bn256PairingPerPointGasIstanbul uint64 = 34000 // Per-point price for an elliptic curve pairing check
|
||||
|
||||
HistoryServeWindow = 8191 // Number of blocks to serve historical block hashes for, EIP-2935.
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -170,3 +176,13 @@ var (
|
|||
|
||||
TargetGasLimit uint64 = XDCGenesisGasLimit // The artificial target
|
||||
)
|
||||
|
||||
// System contracts.
|
||||
var (
|
||||
// SystemAddress is where the system-transaction is sent from as per EIP-2935
|
||||
SystemAddress = common.HexToAddress("0xfffffffffffffffffffffffffffffffffffffffe")
|
||||
|
||||
// EIP-2935 - Serve historical block hashes from state
|
||||
HistoryStorageAddress = common.HexToAddress("0x0000F90827F1C53a10cb7A02335B175320002935")
|
||||
HistoryStorageCode = common.FromHex("3373fffffffffffffffffffffffffffffffffffffffe14604657602036036042575f35600143038111604257611fff81430311604257611fff9006545f5260205ff35b5f5ffd5b5f35611fff60014303065500")
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue