mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32:23 +00:00
implement eip 2935 (#342)
* implement eip 2935 * add touched historical contract slot to the witness
This commit is contained in:
parent
85a7198c2d
commit
ac3f26947d
6 changed files with 59 additions and 1 deletions
|
|
@ -88,6 +88,7 @@ type stEnv struct {
|
|||
ExcessBlobGas *uint64 `json:"excessBlobGas,omitempty"`
|
||||
ParentExcessBlobGas *uint64 `json:"parentExcessBlobGas,omitempty"`
|
||||
ParentBlobGasUsed *uint64 `json:"parentBlobGasUsed,omitempty"`
|
||||
ParentHash *common.Hash `json:"parentHash,omitempty"`
|
||||
}
|
||||
|
||||
type stEnvMarshaling struct {
|
||||
|
|
@ -182,6 +183,9 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||
chainConfig.DAOForkBlock.Cmp(new(big.Int).SetUint64(pre.Env.Number)) == 0 {
|
||||
misc.ApplyDAOHardFork(statedb)
|
||||
}
|
||||
if chainConfig.IsPrague(big.NewInt(int64(pre.Env.Number)), pre.Env.Timestamp) {
|
||||
core.ProcessParentBlockHash(statedb, pre.Env.Number-1, *pre.Env.ParentHash)
|
||||
}
|
||||
var blobGasUsed uint64
|
||||
for i, tx := range txs {
|
||||
if tx.Type() == types.BlobTxType && vmContext.ExcessBlobGas == nil {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ func (s stEnv) MarshalJSON() ([]byte, error) {
|
|||
ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas,omitempty"`
|
||||
ParentExcessBlobGas *math.HexOrDecimal64 `json:"parentExcessBlobGas,omitempty"`
|
||||
ParentBlobGasUsed *math.HexOrDecimal64 `json:"parentBlobGasUsed,omitempty"`
|
||||
ParentHash *common.Hash `json:"parentHash,omitempty"`
|
||||
}
|
||||
var enc stEnv
|
||||
enc.Coinbase = common.UnprefixedAddress(s.Coinbase)
|
||||
|
|
@ -57,6 +58,7 @@ func (s stEnv) MarshalJSON() ([]byte, error) {
|
|||
enc.ExcessBlobGas = (*math.HexOrDecimal64)(s.ExcessBlobGas)
|
||||
enc.ParentExcessBlobGas = (*math.HexOrDecimal64)(s.ParentExcessBlobGas)
|
||||
enc.ParentBlobGasUsed = (*math.HexOrDecimal64)(s.ParentBlobGasUsed)
|
||||
enc.ParentHash = s.ParentHash
|
||||
return json.Marshal(&enc)
|
||||
}
|
||||
|
||||
|
|
@ -82,6 +84,7 @@ func (s *stEnv) UnmarshalJSON(input []byte) error {
|
|||
ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas,omitempty"`
|
||||
ParentExcessBlobGas *math.HexOrDecimal64 `json:"parentExcessBlobGas,omitempty"`
|
||||
ParentBlobGasUsed *math.HexOrDecimal64 `json:"parentBlobGasUsed,omitempty"`
|
||||
ParentHash *common.Hash `json:"parentHash,omitempty"`
|
||||
}
|
||||
var dec stEnv
|
||||
if err := json.Unmarshal(input, &dec); err != nil {
|
||||
|
|
@ -148,5 +151,8 @@ func (s *stEnv) UnmarshalJSON(input []byte) error {
|
|||
if dec.ParentBlobGasUsed != nil {
|
||||
s.ParentBlobGasUsed = (*uint64)(dec.ParentBlobGasUsed)
|
||||
}
|
||||
if dec.ParentHash != nil {
|
||||
s.ParentHash = dec.ParentHash
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,9 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
|||
vmenv = vm.NewEVM(context, vm.TxContext{}, statedb, p.config, cfg)
|
||||
signer = types.MakeSigner(p.config, header.Number, header.Time)
|
||||
)
|
||||
if p.config.IsPrague(block.Number(), block.Time()) {
|
||||
ProcessParentBlockHash(statedb, block.NumberU64()-1, block.ParentHash())
|
||||
}
|
||||
// Iterate over and process the individual transactions
|
||||
for i, tx := range block.Transactions() {
|
||||
msg, err := TransactionToMessage(tx, signer, header.BaseFee)
|
||||
|
|
@ -359,3 +362,9 @@ func (kvm *keyValueMigrator) migrateCollectedKeyValues(tree *trie.VerkleTrie) er
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ProcessParentBlockHash(statedb *state.StateDB, prevNumber uint64, prevHash common.Hash) {
|
||||
var key common.Hash
|
||||
binary.BigEndian.PutUint64(key[24:], prevNumber)
|
||||
statedb.SetState(params.HistoryStorageAddress, key, prevHash)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
package vm
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
|
|
@ -497,6 +499,13 @@ func opGasprice(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func getBlockHashFromContract(number uint64, statedb StateDB, witness *state.AccessWitness) common.Hash {
|
||||
var pnum common.Hash
|
||||
binary.BigEndian.PutUint64(pnum[24:], number)
|
||||
witness.TouchAddressOnReadAndComputeGas(params.HistoryStorageAddress[:], *uint256.NewInt(number / 256), byte(number&0xFF))
|
||||
return statedb.GetState(params.HistoryStorageAddress, pnum)
|
||||
}
|
||||
|
||||
func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
num := scope.Stack.peek()
|
||||
num64, overflow := num.Uint64WithOverflow()
|
||||
|
|
@ -504,6 +513,26 @@ func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) (
|
|||
num.Clear()
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
evm := interpreter.evm
|
||||
bnum := evm.Context.BlockNumber.Uint64()
|
||||
// if Prague is active, check if we are past the 256th block so that
|
||||
// reading from the contract can be activated (EIP 2935).
|
||||
if evm.chainRules.IsPrague && bnum > 256 {
|
||||
if getBlockHashFromContract(bnum-256, evm.StateDB, evm.Accesses) != (common.Hash{}) {
|
||||
// EIP-2935 case: get the block number from the fork, as we are 256 blocks
|
||||
// after the fork activation.
|
||||
|
||||
num.SetBytes(getBlockHashFromContract(num64, evm.StateDB, evm.Accesses).Bytes())
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// if the 256th ancestor didn't have its hash stored in the
|
||||
// history contract, then we are within 256 blocks of the
|
||||
// fork activation, and the former behavior should be retained.
|
||||
// Fall through the legacy use case.
|
||||
}
|
||||
|
||||
var upper, lower uint64
|
||||
upper = interpreter.evm.Context.BlockNumber.Uint64()
|
||||
if upper < 257 {
|
||||
|
|
|
|||
|
|
@ -920,6 +920,9 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) {
|
|||
log.Error("Failed to create sealing context", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
if w.chainConfig.IsPrague(header.Number, header.Time) {
|
||||
core.ProcessParentBlockHash(env.state, header.Number.Uint64()-1, header.ParentHash)
|
||||
}
|
||||
return env, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,11 @@
|
|||
|
||||
package params
|
||||
|
||||
import "math/big"
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
||||
const (
|
||||
GasLimitBoundDivisor uint64 = 1024 // The bound divisor of the gas limit, used in update calculations.
|
||||
|
|
@ -179,4 +183,7 @@ var (
|
|||
GenesisDifficulty = big.NewInt(131072) // Difficulty of the Genesis block.
|
||||
MinimumDifficulty = big.NewInt(131072) // The minimum that the difficulty may ever be.
|
||||
DurationLimit = big.NewInt(13) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not.
|
||||
|
||||
// HistoryStorageAddress is where the historical block hashes are stored.
|
||||
HistoryStorageAddress common.Address = common.HexToAddress("0xfffffffffffffffffffffffffffffffffffffffe")
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue