mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
wip
This commit is contained in:
parent
d4d88f9bce
commit
ef06b2955d
5 changed files with 137 additions and 4 deletions
|
|
@ -139,6 +139,7 @@ type Message struct {
|
||||||
AccessList types.AccessList
|
AccessList types.AccessList
|
||||||
BlobGasFeeCap *big.Int
|
BlobGasFeeCap *big.Int
|
||||||
BlobHashes []common.Hash
|
BlobHashes []common.Hash
|
||||||
|
Delegate bool
|
||||||
|
|
||||||
// When SkipAccountChecks is true, the message nonce is not checked against the
|
// When SkipAccountChecks is true, the message nonce is not checked against the
|
||||||
// account nonce in state. It also disables checking that the sender is an EOA.
|
// account nonce in state. It also disables checking that the sender is an EOA.
|
||||||
|
|
@ -161,6 +162,7 @@ func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.In
|
||||||
SkipAccountChecks: false,
|
SkipAccountChecks: false,
|
||||||
BlobHashes: tx.BlobHashes(),
|
BlobHashes: tx.BlobHashes(),
|
||||||
BlobGasFeeCap: tx.BlobGasFeeCap(),
|
BlobGasFeeCap: tx.BlobGasFeeCap(),
|
||||||
|
Delegate: tx.Delegate(),
|
||||||
}
|
}
|
||||||
// If baseFee provided, set gasPrice to effectiveGasPrice.
|
// If baseFee provided, set gasPrice to effectiveGasPrice.
|
||||||
if baseFee != nil {
|
if baseFee != nil {
|
||||||
|
|
@ -416,7 +418,12 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
|
||||||
} else {
|
} else {
|
||||||
// Increment the nonce for the next transaction
|
// Increment the nonce for the next transaction
|
||||||
st.state.SetNonce(msg.From, st.state.GetNonce(sender.Address())+1)
|
st.state.SetNonce(msg.From, st.state.GetNonce(sender.Address())+1)
|
||||||
|
if !msg.Delegate {
|
||||||
ret, st.gasRemaining, vmerr = st.evm.Call(sender, st.to(), msg.Data, st.gasRemaining, msg.Value)
|
ret, st.gasRemaining, vmerr = st.evm.Call(sender, st.to(), msg.Data, st.gasRemaining, msg.Value)
|
||||||
|
} else {
|
||||||
|
var contract = vm.NewContract(sender, sender, nil, st.gasRemaining)
|
||||||
|
ret, st.gasRemaining, vmerr = st.evm.DelegateCall(contract, st.to(), msg.Data, st.gasRemaining)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !rules.IsLondon {
|
if !rules.IsLondon {
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,9 @@ func ValidateTransaction(tx *types.Transaction, blobs []kzg4844.Blob, commits []
|
||||||
if !opts.Config.IsCancun(head.Number, head.Time) && tx.Type() == types.BlobTxType {
|
if !opts.Config.IsCancun(head.Number, head.Time) && tx.Type() == types.BlobTxType {
|
||||||
return fmt.Errorf("%w: type %d rejected, pool not yet in Cancun", core.ErrTxTypeNotSupported, tx.Type())
|
return fmt.Errorf("%w: type %d rejected, pool not yet in Cancun", core.ErrTxTypeNotSupported, tx.Type())
|
||||||
}
|
}
|
||||||
|
if !opts.Config.IsPrague(head.Number, head.Time) && tx.Type() == types.DelegateTxType {
|
||||||
|
return fmt.Errorf("%w: type %d rejected, pool not yet in Prague", core.ErrTxTypeNotSupported, tx.Type())
|
||||||
|
}
|
||||||
// Check whether the init code size has been exceeded
|
// Check whether the init code size has been exceeded
|
||||||
if opts.Config.IsShanghai(head.Number, head.Time) && tx.To() == nil && len(tx.Data()) > params.MaxInitCodeSize {
|
if opts.Config.IsShanghai(head.Number, head.Time) && tx.To() == nil && len(tx.Data()) > params.MaxInitCodeSize {
|
||||||
return fmt.Errorf("%w: code size %v, limit %v", core.ErrMaxInitCodeSizeExceeded, len(tx.Data()), params.MaxInitCodeSize)
|
return fmt.Errorf("%w: code size %v, limit %v", core.ErrMaxInitCodeSizeExceeded, len(tx.Data()), params.MaxInitCodeSize)
|
||||||
|
|
|
||||||
|
|
@ -194,7 +194,7 @@ func (r *Receipt) decodeTyped(b []byte) error {
|
||||||
return errShortTypedReceipt
|
return errShortTypedReceipt
|
||||||
}
|
}
|
||||||
switch b[0] {
|
switch b[0] {
|
||||||
case DynamicFeeTxType, AccessListTxType, BlobTxType:
|
case DynamicFeeTxType, AccessListTxType, BlobTxType, DelegateTxType:
|
||||||
var data receiptRLP
|
var data receiptRLP
|
||||||
err := rlp.DecodeBytes(b[1:], &data)
|
err := rlp.DecodeBytes(b[1:], &data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -302,7 +302,7 @@ func (rs Receipts) EncodeIndex(i int, w *bytes.Buffer) {
|
||||||
}
|
}
|
||||||
w.WriteByte(r.Type)
|
w.WriteByte(r.Type)
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
case AccessListTxType, DynamicFeeTxType, BlobTxType:
|
case AccessListTxType, DynamicFeeTxType, BlobTxType, DelegateTxType:
|
||||||
rlp.Encode(w, data)
|
rlp.Encode(w, data)
|
||||||
default:
|
default:
|
||||||
// For unsupported types, write nothing. Since this is for
|
// For unsupported types, write nothing. Since this is for
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ const (
|
||||||
AccessListTxType = 0x01
|
AccessListTxType = 0x01
|
||||||
DynamicFeeTxType = 0x02
|
DynamicFeeTxType = 0x02
|
||||||
BlobTxType = 0x03
|
BlobTxType = 0x03
|
||||||
|
DelegateTxType = 0x04
|
||||||
)
|
)
|
||||||
|
|
||||||
// Transaction is an Ethereum transaction.
|
// Transaction is an Ethereum transaction.
|
||||||
|
|
@ -68,7 +69,7 @@ func NewTx(inner TxData) *Transaction {
|
||||||
|
|
||||||
// TxData is the underlying data of a transaction.
|
// TxData is the underlying data of a transaction.
|
||||||
//
|
//
|
||||||
// This is implemented by DynamicFeeTx, LegacyTx and AccessListTx.
|
// This is implemented by DynamicFeeTx, LegacyTx, AccessListTx and DelegateTx.
|
||||||
type TxData interface {
|
type TxData interface {
|
||||||
txType() byte // returns the type ID
|
txType() byte // returns the type ID
|
||||||
copy() TxData // creates a deep copy and initializes all fields
|
copy() TxData // creates a deep copy and initializes all fields
|
||||||
|
|
@ -200,6 +201,10 @@ func (tx *Transaction) decodeTyped(b []byte) (TxData, error) {
|
||||||
var inner BlobTx
|
var inner BlobTx
|
||||||
err := rlp.DecodeBytes(b[1:], &inner)
|
err := rlp.DecodeBytes(b[1:], &inner)
|
||||||
return &inner, err
|
return &inner, err
|
||||||
|
case DelegateTxType:
|
||||||
|
var inner DelegateTx
|
||||||
|
err := rlp.DecodeBytes(b[1:], &inner)
|
||||||
|
return &inner, err
|
||||||
default:
|
default:
|
||||||
return nil, ErrTxTypeNotSupported
|
return nil, ErrTxTypeNotSupported
|
||||||
}
|
}
|
||||||
|
|
@ -264,6 +269,11 @@ func (tx *Transaction) Type() uint8 {
|
||||||
return tx.inner.txType()
|
return tx.inner.txType()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delegate returns wether the transaction type corresponds to a delegate operation or not. (see EIP-5806)
|
||||||
|
func (tx *Transaction) Delegate() bool {
|
||||||
|
return tx.inner.txType() == DelegateTxType
|
||||||
|
}
|
||||||
|
|
||||||
// ChainId returns the EIP155 chain ID of the transaction. The return value will always be
|
// ChainId returns the EIP155 chain ID of the transaction. The return value will always be
|
||||||
// non-nil. For legacy transactions which are not replay-protected, the return value is
|
// non-nil. For legacy transactions which are not replay-protected, the return value is
|
||||||
// zero.
|
// zero.
|
||||||
|
|
|
||||||
113
core/types/tx_delegate.go
Normal file
113
core/types/tx_delegate.go
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
// Copyright 2021 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DelegateTx represents an EIP-5806 transaction.
|
||||||
|
type DelegateTx struct {
|
||||||
|
ChainID *big.Int
|
||||||
|
Nonce uint64
|
||||||
|
GasTipCap *big.Int // a.k.a. maxPriorityFeePerGas
|
||||||
|
GasFeeCap *big.Int // a.k.a. maxFeePerGas
|
||||||
|
Gas uint64
|
||||||
|
To *common.Address `rlp:"nil"` // nil means contract creation
|
||||||
|
Data []byte
|
||||||
|
AccessList AccessList
|
||||||
|
|
||||||
|
// Signature values
|
||||||
|
V *big.Int `json:"v" gencodec:"required"`
|
||||||
|
R *big.Int `json:"r" gencodec:"required"`
|
||||||
|
S *big.Int `json:"s" gencodec:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy creates a deep copy of the transaction data and initializes all fields.
|
||||||
|
func (tx *DelegateTx) copy() TxData {
|
||||||
|
cpy := &DelegateTx{
|
||||||
|
Nonce: tx.Nonce,
|
||||||
|
To: copyAddressPtr(tx.To),
|
||||||
|
Data: common.CopyBytes(tx.Data),
|
||||||
|
Gas: tx.Gas,
|
||||||
|
// These are copied below.
|
||||||
|
AccessList: make(AccessList, len(tx.AccessList)),
|
||||||
|
ChainID: new(big.Int),
|
||||||
|
GasTipCap: new(big.Int),
|
||||||
|
GasFeeCap: new(big.Int),
|
||||||
|
V: new(big.Int),
|
||||||
|
R: new(big.Int),
|
||||||
|
S: new(big.Int),
|
||||||
|
}
|
||||||
|
copy(cpy.AccessList, tx.AccessList)
|
||||||
|
if tx.ChainID != nil {
|
||||||
|
cpy.ChainID.Set(tx.ChainID)
|
||||||
|
}
|
||||||
|
if tx.GasTipCap != nil {
|
||||||
|
cpy.GasTipCap.Set(tx.GasTipCap)
|
||||||
|
}
|
||||||
|
if tx.GasFeeCap != nil {
|
||||||
|
cpy.GasFeeCap.Set(tx.GasFeeCap)
|
||||||
|
}
|
||||||
|
if tx.V != nil {
|
||||||
|
cpy.V.Set(tx.V)
|
||||||
|
}
|
||||||
|
if tx.R != nil {
|
||||||
|
cpy.R.Set(tx.R)
|
||||||
|
}
|
||||||
|
if tx.S != nil {
|
||||||
|
cpy.S.Set(tx.S)
|
||||||
|
}
|
||||||
|
return cpy
|
||||||
|
}
|
||||||
|
|
||||||
|
// accessors for innerTx.
|
||||||
|
func (tx *DelegateTx) txType() byte { return DelegateTxType }
|
||||||
|
func (tx *DelegateTx) chainID() *big.Int { return tx.ChainID }
|
||||||
|
func (tx *DelegateTx) accessList() AccessList { return tx.AccessList }
|
||||||
|
func (tx *DelegateTx) data() []byte { return tx.Data }
|
||||||
|
func (tx *DelegateTx) gas() uint64 { return tx.Gas }
|
||||||
|
func (tx *DelegateTx) gasFeeCap() *big.Int { return tx.GasFeeCap }
|
||||||
|
func (tx *DelegateTx) gasTipCap() *big.Int { return tx.GasTipCap }
|
||||||
|
func (tx *DelegateTx) gasPrice() *big.Int { return tx.GasFeeCap }
|
||||||
|
func (tx *DelegateTx) value() *big.Int { return big.NewInt(0) }
|
||||||
|
func (tx *DelegateTx) nonce() uint64 { return tx.Nonce }
|
||||||
|
func (tx *DelegateTx) to() *common.Address { return tx.To }
|
||||||
|
func (tx *DelegateTx) blobGas() uint64 { return 0 }
|
||||||
|
func (tx *DelegateTx) blobGasFeeCap() *big.Int { return nil }
|
||||||
|
func (tx *DelegateTx) blobHashes() []common.Hash { return nil }
|
||||||
|
|
||||||
|
func (tx *DelegateTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
|
||||||
|
if baseFee == nil {
|
||||||
|
return dst.Set(tx.GasFeeCap)
|
||||||
|
}
|
||||||
|
tip := dst.Sub(tx.GasFeeCap, baseFee)
|
||||||
|
if tip.Cmp(tx.GasTipCap) > 0 {
|
||||||
|
tip.Set(tx.GasTipCap)
|
||||||
|
}
|
||||||
|
return tip.Add(tip, baseFee)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *DelegateTx) rawSignatureValues() (v, r, s *big.Int) {
|
||||||
|
return tx.V, tx.R, tx.S
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *DelegateTx) setSignatureValues(chainID, v, r, s *big.Int) {
|
||||||
|
tx.ChainID, tx.V, tx.R, tx.S = chainID, v, r, s
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue