Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 12 additions & 11 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,18 @@ The state transitioning model does all the necessary work to work out a valid ne
6) Derive new state root
*/
type StateTransition struct {
gp *GasPool
msg Message
gas uint64
gasPrice *big.Int
gasFeeCap *big.Int
gasTipCap *big.Int
initialGas uint64
value *big.Int
data []byte
state vm.StateDB
evm *vm.EVM
gp *GasPool
msg Message
gas uint64
gasPrice *big.Int
gasFeeCap *big.Int
gasTipCap *big.Int
maxFeePerDataGas *big.Int
initialGas uint64
value *big.Int
data []byte
state vm.StateDB
evm *vm.EVM
}

// Message represents a message sent to a contract.
Expand Down
25 changes: 13 additions & 12 deletions core/types/access_list_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,18 +94,19 @@ func (tx *AccessListTx) copy() TxData {
}

// accessors for innerTx.
func (tx *AccessListTx) txType() byte { return AccessListTxType }
func (tx *AccessListTx) chainID() *big.Int { return tx.ChainID }
func (tx *AccessListTx) accessList() AccessList { return tx.AccessList }
func (tx *AccessListTx) dataHashes() []common.Hash { return nil }
func (tx *AccessListTx) data() []byte { return tx.Data }
func (tx *AccessListTx) gas() uint64 { return tx.Gas }
func (tx *AccessListTx) gasPrice() *big.Int { return tx.GasPrice }
func (tx *AccessListTx) gasTipCap() *big.Int { return tx.GasPrice }
func (tx *AccessListTx) gasFeeCap() *big.Int { return tx.GasPrice }
func (tx *AccessListTx) value() *big.Int { return tx.Value }
func (tx *AccessListTx) nonce() uint64 { return tx.Nonce }
func (tx *AccessListTx) to() *common.Address { return tx.To }
func (tx *AccessListTx) txType() byte { return AccessListTxType }
func (tx *AccessListTx) chainID() *big.Int { return tx.ChainID }
func (tx *AccessListTx) accessList() AccessList { return tx.AccessList }
func (tx *AccessListTx) dataHashes() []common.Hash { return nil }
func (tx *AccessListTx) data() []byte { return tx.Data }
func (tx *AccessListTx) gas() uint64 { return tx.Gas }
func (tx *AccessListTx) gasPrice() *big.Int { return tx.GasPrice }
func (tx *AccessListTx) gasTipCap() *big.Int { return tx.GasPrice }
func (tx *AccessListTx) gasFeeCap() *big.Int { return tx.GasPrice }
func (tx *AccessListTx) maxFeePerDataGas() *big.Int { return nil }
func (tx *AccessListTx) value() *big.Int { return tx.Value }
func (tx *AccessListTx) nonce() uint64 { return tx.Nonce }
func (tx *AccessListTx) to() *common.Address { return tx.To }

func (tx *AccessListTx) rawSignatureValues() (v, r, s *big.Int) {
return tx.V, tx.R, tx.S
Expand Down
53 changes: 28 additions & 25 deletions core/types/data_blob_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,37 +316,38 @@ func (alv AccessListView) HashTreeRoot(hFn tree.HashFn) tree.Root {
}

type BlobTxMessage struct {
ChainID Uint256View
Nonce Uint64View
GasTipCap Uint256View // a.k.a. maxPriorityFeePerGas
GasFeeCap Uint256View // a.k.a. maxFeePerGas
Gas Uint64View
To AddressOptionalSSZ // nil means contract creation
Value Uint256View
Data TxDataView
AccessList AccessListView
ChainID Uint256View
Nonce Uint64View
GasTipCap Uint256View // a.k.a. maxPriorityFeePerGas
GasFeeCap Uint256View // a.k.a. maxFeePerGas
Gas Uint64View
To AddressOptionalSSZ // nil means contract creation
Value Uint256View
Data TxDataView
AccessList AccessListView
MaxFeePerDataGas Uint256View

BlobVersionedHashes VersionedHashesView
}

func (tx *BlobTxMessage) Deserialize(dr *codec.DecodingReader) error {
return dr.Container(&tx.ChainID, &tx.Nonce, &tx.GasTipCap, &tx.GasFeeCap, &tx.Gas, &tx.To, &tx.Value, &tx.Data, &tx.AccessList, &tx.BlobVersionedHashes)
return dr.Container(&tx.ChainID, &tx.Nonce, &tx.GasTipCap, &tx.GasFeeCap, &tx.Gas, &tx.To, &tx.Value, &tx.Data, &tx.AccessList, &tx.MaxFeePerDataGas, &tx.BlobVersionedHashes)
}

func (tx *BlobTxMessage) Serialize(w *codec.EncodingWriter) error {
return w.Container(&tx.ChainID, &tx.Nonce, &tx.GasTipCap, &tx.GasFeeCap, &tx.Gas, &tx.To, &tx.Value, &tx.Data, &tx.AccessList, &tx.BlobVersionedHashes)
return w.Container(&tx.ChainID, &tx.Nonce, &tx.GasTipCap, &tx.GasFeeCap, &tx.Gas, &tx.To, &tx.Value, &tx.Data, &tx.AccessList, &tx.MaxFeePerDataGas, &tx.BlobVersionedHashes)
}

func (tx *BlobTxMessage) ByteLength() uint64 {
return codec.ContainerLength(&tx.ChainID, &tx.Nonce, &tx.GasTipCap, &tx.GasFeeCap, &tx.Gas, &tx.To, &tx.Value, &tx.Data, &tx.AccessList, &tx.BlobVersionedHashes)
return codec.ContainerLength(&tx.ChainID, &tx.Nonce, &tx.GasTipCap, &tx.GasFeeCap, &tx.Gas, &tx.To, &tx.Value, &tx.Data, &tx.AccessList, &tx.MaxFeePerDataGas, &tx.BlobVersionedHashes)
}

func (tx *BlobTxMessage) FixedLength() uint64 {
return 0
}

func (tx *BlobTxMessage) HashTreeRoot(hFn tree.HashFn) tree.Root {
return hFn.HashTreeRoot(&tx.ChainID, &tx.Nonce, &tx.GasTipCap, &tx.GasFeeCap, &tx.Gas, &tx.To, &tx.Value, &tx.Data, &tx.AccessList, &tx.BlobVersionedHashes)
return hFn.HashTreeRoot(&tx.ChainID, &tx.Nonce, &tx.GasTipCap, &tx.GasFeeCap, &tx.Gas, &tx.To, &tx.Value, &tx.Data, &tx.AccessList, &tx.MaxFeePerDataGas, &tx.BlobVersionedHashes)
}

// copy creates a deep copy of the transaction data and initializes all fields.
Expand All @@ -361,6 +362,7 @@ func (tx *BlobTxMessage) copy() *BlobTxMessage {
Value: tx.Value,
Data: common.CopyBytes(tx.Data),
AccessList: make([]AccessTuple, len(tx.AccessList)),
MaxFeePerDataGas: tx.MaxFeePerDataGas,
BlobVersionedHashes: make([]common.Hash, len(tx.BlobVersionedHashes)),
}
copy(cpy.AccessList, tx.AccessList)
Expand Down Expand Up @@ -416,18 +418,19 @@ func u256ToBig(v *Uint256View) *big.Int {
}

// accessors for innerTx.
func (stx *SignedBlobTx) txType() byte { return BlobTxType }
func (stx *SignedBlobTx) chainID() *big.Int { return u256ToBig(&stx.Message.ChainID) }
func (stx *SignedBlobTx) accessList() AccessList { return AccessList(stx.Message.AccessList) }
func (stx *SignedBlobTx) dataHashes() []common.Hash { return stx.Message.BlobVersionedHashes }
func (stx *SignedBlobTx) data() []byte { return stx.Message.Data }
func (stx *SignedBlobTx) gas() uint64 { return uint64(stx.Message.Gas) }
func (stx *SignedBlobTx) gasFeeCap() *big.Int { return u256ToBig(&stx.Message.GasFeeCap) }
func (stx *SignedBlobTx) gasTipCap() *big.Int { return u256ToBig(&stx.Message.GasTipCap) }
func (stx *SignedBlobTx) gasPrice() *big.Int { return u256ToBig(&stx.Message.GasFeeCap) }
func (stx *SignedBlobTx) value() *big.Int { return u256ToBig(&stx.Message.Value) }
func (stx *SignedBlobTx) nonce() uint64 { return uint64(stx.Message.Nonce) }
func (stx *SignedBlobTx) to() *common.Address { return (*common.Address)(stx.Message.To.Address) }
func (stx *SignedBlobTx) txType() byte { return BlobTxType }
func (stx *SignedBlobTx) chainID() *big.Int { return u256ToBig(&stx.Message.ChainID) }
func (stx *SignedBlobTx) accessList() AccessList { return AccessList(stx.Message.AccessList) }
func (stx *SignedBlobTx) dataHashes() []common.Hash { return stx.Message.BlobVersionedHashes }
func (stx *SignedBlobTx) data() []byte { return stx.Message.Data }
func (stx *SignedBlobTx) gas() uint64 { return uint64(stx.Message.Gas) }
func (stx *SignedBlobTx) gasFeeCap() *big.Int { return u256ToBig(&stx.Message.GasFeeCap) }
func (stx *SignedBlobTx) gasTipCap() *big.Int { return u256ToBig(&stx.Message.GasTipCap) }
func (stx *SignedBlobTx) maxFeePerDataGas() *big.Int { return u256ToBig(&stx.Message.MaxFeePerDataGas) }
func (stx *SignedBlobTx) gasPrice() *big.Int { return u256ToBig(&stx.Message.GasFeeCap) }
func (stx *SignedBlobTx) value() *big.Int { return u256ToBig(&stx.Message.Value) }
func (stx *SignedBlobTx) nonce() uint64 { return uint64(stx.Message.Nonce) }
func (stx *SignedBlobTx) to() *common.Address { return (*common.Address)(stx.Message.To.Address) }

func (stx *SignedBlobTx) rawSignatureValues() (v, r, s *big.Int) {
return big.NewInt(int64(stx.Signature.V)), u256ToBig(&stx.Signature.R), u256ToBig(&stx.Signature.S)
Expand Down
25 changes: 13 additions & 12 deletions core/types/dynamic_fee_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,18 +82,19 @@ func (tx *DynamicFeeTx) copy() TxData {
}

// accessors for innerTx.
func (tx *DynamicFeeTx) txType() byte { return DynamicFeeTxType }
func (tx *DynamicFeeTx) chainID() *big.Int { return tx.ChainID }
func (tx *DynamicFeeTx) accessList() AccessList { return tx.AccessList }
func (tx *DynamicFeeTx) dataHashes() []common.Hash { return nil }
func (tx *DynamicFeeTx) data() []byte { return tx.Data }
func (tx *DynamicFeeTx) gas() uint64 { return tx.Gas }
func (tx *DynamicFeeTx) gasFeeCap() *big.Int { return tx.GasFeeCap }
func (tx *DynamicFeeTx) gasTipCap() *big.Int { return tx.GasTipCap }
func (tx *DynamicFeeTx) gasPrice() *big.Int { return tx.GasFeeCap }
func (tx *DynamicFeeTx) value() *big.Int { return tx.Value }
func (tx *DynamicFeeTx) nonce() uint64 { return tx.Nonce }
func (tx *DynamicFeeTx) to() *common.Address { return tx.To }
func (tx *DynamicFeeTx) txType() byte { return DynamicFeeTxType }
func (tx *DynamicFeeTx) chainID() *big.Int { return tx.ChainID }
func (tx *DynamicFeeTx) accessList() AccessList { return tx.AccessList }
func (tx *DynamicFeeTx) dataHashes() []common.Hash { return nil }
func (tx *DynamicFeeTx) data() []byte { return tx.Data }
func (tx *DynamicFeeTx) gas() uint64 { return tx.Gas }
func (tx *DynamicFeeTx) gasFeeCap() *big.Int { return tx.GasFeeCap }
func (tx *DynamicFeeTx) gasTipCap() *big.Int { return tx.GasTipCap }
func (tx *DynamicFeeTx) maxFeePerDataGas() *big.Int { return nil }
func (tx *DynamicFeeTx) gasPrice() *big.Int { return tx.GasFeeCap }
func (tx *DynamicFeeTx) value() *big.Int { return tx.Value }
func (tx *DynamicFeeTx) nonce() uint64 { return tx.Nonce }
func (tx *DynamicFeeTx) to() *common.Address { return tx.To }

func (tx *DynamicFeeTx) rawSignatureValues() (v, r, s *big.Int) {
return tx.V, tx.R, tx.S
Expand Down
25 changes: 13 additions & 12 deletions core/types/legacy_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,18 +91,19 @@ func (tx *LegacyTx) copy() TxData {
}

// accessors for innerTx.
func (tx *LegacyTx) txType() byte { return LegacyTxType }
func (tx *LegacyTx) chainID() *big.Int { return deriveChainId(tx.V) }
func (tx *LegacyTx) accessList() AccessList { return nil }
func (tx *LegacyTx) dataHashes() []common.Hash { return nil }
func (tx *LegacyTx) data() []byte { return tx.Data }
func (tx *LegacyTx) gas() uint64 { return tx.Gas }
func (tx *LegacyTx) gasPrice() *big.Int { return tx.GasPrice }
func (tx *LegacyTx) gasTipCap() *big.Int { return tx.GasPrice }
func (tx *LegacyTx) gasFeeCap() *big.Int { return tx.GasPrice }
func (tx *LegacyTx) value() *big.Int { return tx.Value }
func (tx *LegacyTx) nonce() uint64 { return tx.Nonce }
func (tx *LegacyTx) to() *common.Address { return tx.To }
func (tx *LegacyTx) txType() byte { return LegacyTxType }
func (tx *LegacyTx) chainID() *big.Int { return deriveChainId(tx.V) }
func (tx *LegacyTx) accessList() AccessList { return nil }
func (tx *LegacyTx) dataHashes() []common.Hash { return nil }
func (tx *LegacyTx) data() []byte { return tx.Data }
func (tx *LegacyTx) gas() uint64 { return tx.Gas }
func (tx *LegacyTx) gasPrice() *big.Int { return tx.GasPrice }
func (tx *LegacyTx) gasTipCap() *big.Int { return tx.GasPrice }
func (tx *LegacyTx) gasFeeCap() *big.Int { return tx.GasPrice }
func (tx *LegacyTx) maxFeePerDataGas() *big.Int { return nil }
func (tx *LegacyTx) value() *big.Int { return tx.Value }
func (tx *LegacyTx) nonce() uint64 { return tx.Nonce }
func (tx *LegacyTx) to() *common.Address { return tx.To }

func (tx *LegacyTx) rawSignatureValues() (v, r, s *big.Int) {
return tx.V, tx.R, tx.S
Expand Down
8 changes: 7 additions & 1 deletion core/types/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ type TxWrapData interface {

// TxData is the underlying data of a transaction.
//
// This is implemented by DynamicFeeTx, LegacyTx and AccessListTx.
// This is implemented by DynamicFeeTx, LegacyTx, AccessListTx & SignedBlobTx.
type TxData interface {
txType() byte // returns the type ID
copy() TxData // creates a deep copy and initializes all fields
Expand All @@ -115,6 +115,7 @@ type TxData interface {
gasPrice() *big.Int
gasTipCap() *big.Int
gasFeeCap() *big.Int
maxFeePerDataGas() *big.Int
value() *big.Int
nonce() uint64
to() *common.Address
Expand Down Expand Up @@ -385,6 +386,11 @@ func (tx *Transaction) GasTipCap() *big.Int { return new(big.Int).Set(tx.inner.g
// GasFeeCap returns the fee cap per gas of the transaction.
func (tx *Transaction) GasFeeCap() *big.Int { return new(big.Int).Set(tx.inner.gasFeeCap()) }

// MaxFeePerDataGas returns the max_fee_per_data_gas value for the transaction
func (tx *Transaction) MaxFeePerDataGas() *big.Int {
return new(big.Int).Set(tx.inner.maxFeePerDataGas())
}

// Value returns the ether amount of the transaction.
func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.inner.value()) }

Expand Down
19 changes: 10 additions & 9 deletions interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,17 +132,18 @@ type ChainSyncReader interface {

// CallMsg contains parameters for contract calls.
type CallMsg struct {
From common.Address // the sender of the 'transaction'
To *common.Address // the destination contract (nil for contract creation)
Gas uint64 // if 0, the call executes with near-infinite gas
GasPrice *big.Int // wei <-> gas exchange ratio
GasFeeCap *big.Int // EIP-1559 fee cap per gas.
GasTipCap *big.Int // EIP-1559 tip per gas.
Value *big.Int // amount of wei sent along with the call
Data []byte // input data, usually an ABI-encoded contract method invocation
From common.Address // the sender of the 'transaction'
To *common.Address // the destination contract (nil for contract creation)
Gas uint64 // if 0, the call executes with near-infinite gas
GasPrice *big.Int // wei <-> gas exchange ratio
GasFeeCap *big.Int // EIP-1559 fee cap per gas.
GasTipCap *big.Int // EIP-1559 tip per gas.
MaxFeePerDataGas *big.Int // EIP-4844 max_fee_per_data_gas
Value *big.Int // amount of wei sent along with the call
Data []byte // input data, usually an ABI-encoded contract method invocation

AccessList types.AccessList // EIP-2930 access list.
DataHashes []common.Hash // versioned data hashes for mini-danksharding
DataHashes []common.Hash // versioned data hashes for EIP-4844
}

// A ContractCaller provides contract calls, essentially transactions that are executed by
Expand Down
3 changes: 3 additions & 0 deletions internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ func (s *TxPoolAPI) Inspect() map[string]map[string]map[string]string {

// Define a formatter to flatten a transaction into a string
var format = func(tx *types.Transaction) string {
// TODO: handle data gas for txs with blobs (EIP-4844)
if to := tx.To(); to != nil {
return fmt.Sprintf("%s: %v wei + %v gas × %v wei", tx.To().Hex(), tx.Value(), tx.Gas(), tx.GasPrice())
}
Expand Down Expand Up @@ -1264,6 +1265,7 @@ type RPCTransaction struct {
Value *hexutil.Big `json:"value"`
Type hexutil.Uint64 `json:"type"`
Accesses *types.AccessList `json:"accessList,omitempty"`
MaxFeePerDataGas *hexutil.Big `json:"maxFeePerDataGas,omitempty"`
BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"`
ChainID *hexutil.Big `json:"chainId,omitempty"`
V *hexutil.Big `json:"v"`
Expand Down Expand Up @@ -1313,6 +1315,7 @@ func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber
result.ChainID = (*hexutil.Big)(tx.ChainId())
result.GasFeeCap = (*hexutil.Big)(tx.GasFeeCap())
result.GasTipCap = (*hexutil.Big)(tx.GasTipCap())
result.MaxFeePerDataGas = (*hexutil.Big)(tx.MaxFeePerDataGas())
// if the transaction has been mined, compute the effective gas price
if baseFee != nil && blockHash != (common.Hash{}) {
// price = min(tip, gasFeeCap - baseFee) + baseFee
Expand Down