mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
cmd/evm: refactor t8n for clarity
This commit is contained in:
parent
dbc1aacc6a
commit
2b67330782
1 changed files with 146 additions and 103 deletions
|
|
@ -192,113 +192,20 @@ func Transition(ctx *cli.Context) error {
|
|||
// Set the chain id
|
||||
chainConfig.ChainID = big.NewInt(ctx.Int64(ChainIDFlag.Name))
|
||||
|
||||
var txsWithKeys []*txWithKey
|
||||
if txStr != stdinSelector {
|
||||
inFile, err := os.Open(txStr)
|
||||
if err != nil {
|
||||
return NewError(ErrorIO, fmt.Errorf("failed reading txs file: %v", err))
|
||||
}
|
||||
defer inFile.Close()
|
||||
decoder := json.NewDecoder(inFile)
|
||||
if strings.HasSuffix(txStr, ".rlp") {
|
||||
var body hexutil.Bytes
|
||||
if err := decoder.Decode(&body); err != nil {
|
||||
return err
|
||||
}
|
||||
var txs types.Transactions
|
||||
if err := rlp.DecodeBytes(body, &txs); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, tx := range txs {
|
||||
txsWithKeys = append(txsWithKeys, &txWithKey{
|
||||
key: nil,
|
||||
tx: tx,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if err := decoder.Decode(&txsWithKeys); err != nil {
|
||||
return NewError(ErrorJson, fmt.Errorf("failed unmarshaling txs-file: %v", err))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if len(inputData.TxRlp) > 0 {
|
||||
// Decode the body of already signed transactions
|
||||
body := common.FromHex(inputData.TxRlp)
|
||||
var txs types.Transactions
|
||||
if err := rlp.DecodeBytes(body, &txs); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, tx := range txs {
|
||||
txsWithKeys = append(txsWithKeys, &txWithKey{
|
||||
key: nil,
|
||||
tx: tx,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// JSON encoded transactions
|
||||
txsWithKeys = inputData.Txs
|
||||
}
|
||||
if txs, err = loadTransactions(txStr, inputData, prestate.Env, chainConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
// We may have to sign the transactions.
|
||||
signer := types.MakeSigner(chainConfig, big.NewInt(int64(prestate.Env.Number)), prestate.Env.Timestamp)
|
||||
|
||||
if txs, err = signUnsignedTransactions(txsWithKeys, signer); err != nil {
|
||||
return NewError(ErrorJson, fmt.Errorf("failed signing transactions: %v", err))
|
||||
if err := applyLondonChecks(&prestate.Env, chainConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
// Sanity check, to not `panic` in state_transition
|
||||
if chainConfig.IsLondon(big.NewInt(int64(prestate.Env.Number))) {
|
||||
if prestate.Env.BaseFee != nil {
|
||||
// Already set, base fee has precedent over parent base fee.
|
||||
} else if prestate.Env.ParentBaseFee != nil && prestate.Env.Number != 0 {
|
||||
parent := &types.Header{
|
||||
Number: new(big.Int).SetUint64(prestate.Env.Number - 1),
|
||||
BaseFee: prestate.Env.ParentBaseFee,
|
||||
GasUsed: prestate.Env.ParentGasUsed,
|
||||
GasLimit: prestate.Env.ParentGasLimit,
|
||||
}
|
||||
prestate.Env.BaseFee = eip1559.CalcBaseFee(chainConfig, parent)
|
||||
} else {
|
||||
return NewError(ErrorConfig, errors.New("EIP-1559 config but missing 'currentBaseFee' in env section"))
|
||||
}
|
||||
if err := applyShanghaiChecks(&prestate.Env, chainConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
if chainConfig.IsShanghai(big.NewInt(int64(prestate.Env.Number)), prestate.Env.Timestamp) && prestate.Env.Withdrawals == nil {
|
||||
return NewError(ErrorConfig, errors.New("Shanghai config but missing 'withdrawals' in env section"))
|
||||
if err := applyMergeChecks(&prestate.Env, chainConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
isMerged := chainConfig.TerminalTotalDifficulty != nil && chainConfig.TerminalTotalDifficulty.BitLen() == 0
|
||||
env := prestate.Env
|
||||
if isMerged {
|
||||
// post-merge:
|
||||
// - random must be supplied
|
||||
// - difficulty must be zero
|
||||
switch {
|
||||
case env.Random == nil:
|
||||
return NewError(ErrorConfig, errors.New("post-merge requires currentRandom to be defined in env"))
|
||||
case env.Difficulty != nil && env.Difficulty.BitLen() != 0:
|
||||
return NewError(ErrorConfig, errors.New("post-merge difficulty must be zero (or omitted) in env"))
|
||||
}
|
||||
prestate.Env.Difficulty = nil
|
||||
} else if env.Difficulty == nil {
|
||||
// pre-merge:
|
||||
// If difficulty was not provided by caller, we need to calculate it.
|
||||
switch {
|
||||
case env.ParentDifficulty == nil:
|
||||
return NewError(ErrorConfig, errors.New("currentDifficulty was not provided, and cannot be calculated due to missing parentDifficulty"))
|
||||
case env.Number == 0:
|
||||
return NewError(ErrorConfig, errors.New("currentDifficulty needs to be provided for block number 0"))
|
||||
case env.Timestamp <= env.ParentTimestamp:
|
||||
return NewError(ErrorConfig, fmt.Errorf("currentDifficulty cannot be calculated -- currentTime (%d) needs to be after parent time (%d)",
|
||||
env.Timestamp, env.ParentTimestamp))
|
||||
}
|
||||
prestate.Env.Difficulty = calcDifficulty(chainConfig, env.Number, env.Timestamp,
|
||||
env.ParentTimestamp, env.ParentDifficulty, env.ParentUncleHash)
|
||||
}
|
||||
if chainConfig.IsCancun(big.NewInt(int64(prestate.Env.Number)), prestate.Env.Timestamp) {
|
||||
// We require EIP-4788 beacon root to be set in the env
|
||||
if env.ParentBeaconBlockRoot == nil {
|
||||
return NewError(ErrorConfig, errors.New("post-cancun env requires parentBeaconBlockRoot to be set"))
|
||||
}
|
||||
} else {
|
||||
env.ParentBeaconBlockRoot = nil // un-set it if it has been set too early
|
||||
if err := applyCancunChecks(&prestate.Env, chainConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
// Run the test and aggregate the result
|
||||
s, result, err := prestate.Apply(vmConfig, chainConfig, txs, ctx.Int64(RewardFlag.Name), getTracer)
|
||||
|
|
@ -393,6 +300,142 @@ func signUnsignedTransactions(txs []*txWithKey, signer types.Signer) (types.Tran
|
|||
return signedTxs, nil
|
||||
}
|
||||
|
||||
func loadTransactions(txStr string, inputData *input, env stEnv, chainConfig *params.ChainConfig) (types.Transactions, error) {
|
||||
var txsWithKeys []*txWithKey
|
||||
if txStr != stdinSelector {
|
||||
inFile, err := os.Open(txStr)
|
||||
if err != nil {
|
||||
return nil, NewError(ErrorIO, fmt.Errorf("failed reading txs file: %v", err))
|
||||
}
|
||||
defer inFile.Close()
|
||||
decoder := json.NewDecoder(inFile)
|
||||
if strings.HasSuffix(txStr, ".rlp") {
|
||||
var body hexutil.Bytes
|
||||
if err := decoder.Decode(&body); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var txs types.Transactions
|
||||
if err := rlp.DecodeBytes(body, &txs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, tx := range txs {
|
||||
txsWithKeys = append(txsWithKeys, &txWithKey{
|
||||
key: nil,
|
||||
tx: tx,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if err := decoder.Decode(&txsWithKeys); err != nil {
|
||||
return nil, NewError(ErrorJson, fmt.Errorf("failed unmarshaling txs-file: %v", err))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if len(inputData.TxRlp) > 0 {
|
||||
// Decode the body of already signed transactions
|
||||
body := common.FromHex(inputData.TxRlp)
|
||||
var txs types.Transactions
|
||||
if err := rlp.DecodeBytes(body, &txs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, tx := range txs {
|
||||
txsWithKeys = append(txsWithKeys, &txWithKey{
|
||||
key: nil,
|
||||
tx: tx,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// JSON encoded transactions
|
||||
txsWithKeys = inputData.Txs
|
||||
}
|
||||
}
|
||||
// We may have to sign the transactions.
|
||||
signer := types.MakeSigner(chainConfig, big.NewInt(int64(env.Number)), env.Timestamp)
|
||||
|
||||
if txs, err := signUnsignedTransactions(txsWithKeys, signer); err != nil {
|
||||
return nil, NewError(ErrorJson, fmt.Errorf("failed signing transactions: %v", err))
|
||||
} else {
|
||||
return txs, err
|
||||
}
|
||||
}
|
||||
|
||||
func applyLondonChecks(env *stEnv, chainConfig *params.ChainConfig) error {
|
||||
if !chainConfig.IsLondon(big.NewInt(int64(env.Number))) {
|
||||
return nil
|
||||
}
|
||||
// Sanity check, to not `panic` in state_transition
|
||||
if env.BaseFee != nil {
|
||||
// Already set, base fee has precedent over parent base fee.
|
||||
return nil
|
||||
}
|
||||
if env.ParentBaseFee == nil || env.Number == 0 {
|
||||
return NewError(ErrorConfig, errors.New("EIP-1559 config but missing 'currentBaseFee' in env section"))
|
||||
}
|
||||
env.BaseFee = eip1559.CalcBaseFee(chainConfig, &types.Header{
|
||||
Number: new(big.Int).SetUint64(env.Number - 1),
|
||||
BaseFee: env.ParentBaseFee,
|
||||
GasUsed: env.ParentGasUsed,
|
||||
GasLimit: env.ParentGasLimit,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func applyShanghaiChecks(env *stEnv, chainConfig *params.ChainConfig) error {
|
||||
if !chainConfig.IsShanghai(big.NewInt(int64(env.Number)), env.Timestamp) {
|
||||
return nil
|
||||
}
|
||||
if env.Withdrawals == nil {
|
||||
return NewError(ErrorConfig, errors.New("Shanghai config but missing 'withdrawals' in env section"))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func applyMergeChecks(env *stEnv, chainConfig *params.ChainConfig) error {
|
||||
isMerged := chainConfig.TerminalTotalDifficulty != nil && chainConfig.TerminalTotalDifficulty.BitLen() == 0
|
||||
if !isMerged {
|
||||
// pre-merge: If difficulty was not provided by caller, we need to calculate it.
|
||||
if env.Difficulty != nil {
|
||||
// already set
|
||||
return nil
|
||||
}
|
||||
switch {
|
||||
case env.ParentDifficulty == nil:
|
||||
return NewError(ErrorConfig, errors.New("currentDifficulty was not provided, and cannot be calculated due to missing parentDifficulty"))
|
||||
case env.Number == 0:
|
||||
return NewError(ErrorConfig, errors.New("currentDifficulty needs to be provided for block number 0"))
|
||||
case env.Timestamp <= env.ParentTimestamp:
|
||||
return NewError(ErrorConfig, fmt.Errorf("currentDifficulty cannot be calculated -- currentTime (%d) needs to be after parent time (%d)",
|
||||
env.Timestamp, env.ParentTimestamp))
|
||||
}
|
||||
env.Difficulty = calcDifficulty(chainConfig, env.Number, env.Timestamp,
|
||||
env.ParentTimestamp, env.ParentDifficulty, env.ParentUncleHash)
|
||||
return nil
|
||||
}
|
||||
// post-merge:
|
||||
// - random must be supplied
|
||||
// - difficulty must be zero
|
||||
switch {
|
||||
case env.Random == nil:
|
||||
return NewError(ErrorConfig, errors.New("post-merge requires currentRandom to be defined in env"))
|
||||
case env.Difficulty != nil && env.Difficulty.BitLen() != 0:
|
||||
return NewError(ErrorConfig, errors.New("post-merge difficulty must be zero (or omitted) in env"))
|
||||
}
|
||||
env.Difficulty = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func applyCancunChecks(env *stEnv, chainConfig *params.ChainConfig) error {
|
||||
if !chainConfig.IsCancun(big.NewInt(int64(env.Number)), env.Timestamp) {
|
||||
env.ParentBeaconBlockRoot = nil // un-set it if it has been set too early
|
||||
return nil
|
||||
}
|
||||
// Post-cancun
|
||||
// We require EIP-4788 beacon root to be set in the env
|
||||
if env.ParentBeaconBlockRoot == nil {
|
||||
return NewError(ErrorConfig, errors.New("post-cancun env requires parentBeaconBlockRoot to be set"))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Alloc map[common.Address]core.GenesisAccount
|
||||
|
||||
func (g Alloc) OnRoot(common.Hash) {}
|
||||
|
|
|
|||
Loading…
Reference in a new issue