Update types for cancun

This commit is contained in:
Austin Roberts 2024-01-16 17:13:21 -06:00
parent 582bfa8e6a
commit 7bac6be2d4
7 changed files with 94 additions and 15 deletions

View File

@ -152,6 +152,19 @@ const (
Bls12381MapG1Gas uint64 = 5500 // Gas price for BLS12-381 mapping field element to G1 operation Bls12381MapG1Gas uint64 = 5500 // Gas price for BLS12-381 mapping field element to G1 operation
Bls12381MapG2Gas uint64 = 110000 // Gas price for BLS12-381 mapping field element to G2 operation Bls12381MapG2Gas uint64 = 110000 // Gas price for BLS12-381 mapping field element to G2 operation
BlobTxHashVersion = 0x01 // Version byte of the commitment hash
BlobTxMaxDataGasPerBlock = 1 << 19 // Maximum consumable data gas for data blobs per block
BlobTxTargetDataGasPerBlock = 1 << 18 // Target consumable data gas for data blobs per block (for 1559-like pricing)
BlobTxDataGasPerBlob = 1 << 17 // Gas consumption of a single data blob (== blob byte size)
BlobTxMinDataGasprice = 1 // Minimum gas price for data blobs
BlobTxDataGaspriceUpdateFraction = 2225652 // Controls the maximum rate of change for data gas price
BlobTxPointEvaluationPrecompileGas = 50000 // Gas price for the point evaluation precompile.
BlobTxTargetBlobGasPerBlock = 1 << 18 // Target consumable blob gas for data blobs per block (for 1559-like pricing)
BlobTxMinBlobGasprice = 1 // Minimum gas price for data blobs
BlobTxBlobGaspriceUpdateFraction = 2225652 // Controls the maximum rate of change for blob gas price
// The Refund Quotient is the cap on how much of the used gas can be refunded. Before EIP-3529, // The Refund Quotient is the cap on how much of the used gas can be refunded. Before EIP-3529,
// up to half the consumed gas could be refunded. Redefined as 1/5th in EIP-3529 // up to half the consumed gas could be refunded. Redefined as 1/5th in EIP-3529
RefundQuotient uint64 = 2 RefundQuotient uint64 = 2

View File

@ -105,6 +105,9 @@ func (tx *AccessListTx) gasFeeCap() *big.Int { return tx.GasPrice }
func (tx *AccessListTx) value() *big.Int { return tx.Value } func (tx *AccessListTx) value() *big.Int { return tx.Value }
func (tx *AccessListTx) nonce() uint64 { return tx.Nonce } func (tx *AccessListTx) nonce() uint64 { return tx.Nonce }
func (tx *AccessListTx) to() *core.Address { return tx.To } func (tx *AccessListTx) to() *core.Address { return tx.To }
func (tx *AccessListTx) blobGas() uint64 { return 0}
func (tx *AccessListTx) blobGasFeeCap() *big.Int { return nil }
func (tx *AccessListTx) blobHashes() []core.Hash { return nil }
func (tx *AccessListTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int { func (tx *AccessListTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
return dst.Set(tx.GasPrice) return dst.Set(tx.GasPrice)

View File

@ -90,11 +90,14 @@ type Header struct {
// WithdrawalsHash was added by EIP-4895 and is ignored in legacy headers. // WithdrawalsHash was added by EIP-4895 and is ignored in legacy headers.
WithdrawalsHash *core.Hash `json:"withdrawalsRoot" rlp:"optional"` WithdrawalsHash *core.Hash `json:"withdrawalsRoot" rlp:"optional"`
/* // BlobGasUsed was added by EIP-4844 and is ignored in legacy headers.
TODO (MariusVanDerWijden) Add this field once needed BlobGasUsed *uint64 `json:"blobGasUsed" rlp:"optional"`
// Random was added during the merge and contains the BeaconState randomness
Random core.Hash `json:"random" rlp:"optional"` // ExcessBlobGas was added by EIP-4844 and is ignored in legacy headers.
*/ ExcessBlobGas *uint64 `json:"excessBlobGas" rlp:"optional"`
// ParentBeaconRoot was added by EIP-4788 and is ignored in legacy headers.
ParentBeaconRoot *core.Hash `json:"parentBeaconBlockRoot" rlp:"optional"`
} }
// field type overrides for gencodec // field type overrides for gencodec
@ -283,6 +286,18 @@ func CopyHeader(h *Header) *Header {
if h.WithdrawalsHash != nil { if h.WithdrawalsHash != nil {
*cpy.WithdrawalsHash = *h.WithdrawalsHash *cpy.WithdrawalsHash = *h.WithdrawalsHash
} }
if h.ExcessBlobGas != nil {
cpy.ExcessBlobGas = new(uint64)
*cpy.ExcessBlobGas = *h.ExcessBlobGas
}
if h.BlobGasUsed != nil {
cpy.BlobGasUsed = new(uint64)
*cpy.BlobGasUsed = *h.BlobGasUsed
}
if h.ParentBeaconRoot != nil {
cpy.ParentBeaconRoot = new(core.Hash)
*cpy.ParentBeaconRoot = *h.ParentBeaconRoot
}
return &cpy return &cpy
} }
@ -347,6 +362,26 @@ func (b *Block) BaseFee() *big.Int {
return new(big.Int).Set(b.header.BaseFee) return new(big.Int).Set(b.header.BaseFee)
} }
func (b *Block) BeaconRoot() *core.Hash { return b.header.ParentBeaconRoot }
func (b *Block) ExcessBlobGas() *uint64 {
var excessBlobGas *uint64
if b.header.ExcessBlobGas != nil {
excessBlobGas = new(uint64)
*excessBlobGas = *b.header.ExcessBlobGas
}
return excessBlobGas
}
func (b *Block) BlobGasUsed() *uint64 {
var blobGasUsed *uint64
if b.header.BlobGasUsed != nil {
blobGasUsed = new(uint64)
*blobGasUsed = *b.header.BlobGasUsed
}
return blobGasUsed
}
func (b *Block) Withdrawals() Withdrawals { func (b *Block) Withdrawals() Withdrawals {
return b.withdrawals return b.withdrawals
} }
@ -391,10 +426,8 @@ func CalcUncleHash(uncles []*Header) core.Hash {
// WithSeal returns a new block with the data from b but the header replaced with // WithSeal returns a new block with the data from b but the header replaced with
// the sealed one. // the sealed one.
func (b *Block) WithSeal(header *Header) *Block { func (b *Block) WithSeal(header *Header) *Block {
cpy := *header
return &Block{ return &Block{
header: &cpy, header: CopyHeader(header),
transactions: b.transactions, transactions: b.transactions,
uncles: b.uncles, uncles: b.uncles,
withdrawals: b.withdrawals, withdrawals: b.withdrawals,
@ -407,6 +440,7 @@ func (b *Block) WithBody(transactions []*Transaction, uncles []*Header) *Block {
header: CopyHeader(b.header), header: CopyHeader(b.header),
transactions: make([]*Transaction, len(transactions)), transactions: make([]*Transaction, len(transactions)),
uncles: make([]*Header, len(uncles)), uncles: make([]*Header, len(uncles)),
withdrawals: b.withdrawals,
} }
copy(block.transactions, transactions) copy(block.transactions, transactions)
for i := range uncles { for i := range uncles {
@ -417,11 +451,16 @@ func (b *Block) WithBody(transactions []*Transaction, uncles []*Header) *Block {
// WithWithdrawals sets the withdrawal contents of a block, does not return a new block. // WithWithdrawals sets the withdrawal contents of a block, does not return a new block.
func (b *Block) WithWithdrawals(withdrawals []*Withdrawal) *Block { func (b *Block) WithWithdrawals(withdrawals []*Withdrawal) *Block {
if withdrawals != nil { block := &Block{
b.withdrawals = make([]*Withdrawal, len(withdrawals)) header: b.header,
copy(b.withdrawals, withdrawals) transactions: b.transactions,
uncles: b.uncles,
} }
return b if withdrawals != nil {
block.withdrawals = make([]*Withdrawal, len(withdrawals))
copy(block.withdrawals, withdrawals)
}
return block
} }
// Hash returns the keccak256 hash of b's header. // Hash returns the keccak256 hash of b's header.

View File

@ -93,6 +93,9 @@ func (tx *DynamicFeeTx) gasPrice() *big.Int { return tx.GasFeeCap }
func (tx *DynamicFeeTx) value() *big.Int { return tx.Value } func (tx *DynamicFeeTx) value() *big.Int { return tx.Value }
func (tx *DynamicFeeTx) nonce() uint64 { return tx.Nonce } func (tx *DynamicFeeTx) nonce() uint64 { return tx.Nonce }
func (tx *DynamicFeeTx) to() *core.Address { return tx.To } func (tx *DynamicFeeTx) to() *core.Address { return tx.To }
func (tx *DynamicFeeTx) blobGas() uint64 { return 0}
func (tx *DynamicFeeTx) blobGasFeeCap() *big.Int { return nil }
func (tx *DynamicFeeTx) blobHashes() []core.Hash { return nil }
func (tx *DynamicFeeTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int { func (tx *DynamicFeeTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
if baseFee == nil { if baseFee == nil {

View File

@ -136,10 +136,9 @@ func (d *hashToHumanReadable) Reset() {
d.data = make([]byte, 0) d.data = make([]byte, 0)
} }
func (d *hashToHumanReadable) Update(i []byte, i2 []byte) error { func (d *hashToHumanReadable) Update(i []byte, i2 []byte) {
l := fmt.Sprintf("%x %x\n", i, i2) l := fmt.Sprintf("%x %x\n", i, i2)
d.data = append(d.data, []byte(l)...) d.data = append(d.data, []byte(l)...)
return nil
} }
func (d *hashToHumanReadable) Hash() core.Hash { func (d *hashToHumanReadable) Hash() core.Hash {

View File

@ -102,6 +102,9 @@ func (tx *LegacyTx) gasFeeCap() *big.Int { return tx.GasPrice }
func (tx *LegacyTx) value() *big.Int { return tx.Value } func (tx *LegacyTx) value() *big.Int { return tx.Value }
func (tx *LegacyTx) nonce() uint64 { return tx.Nonce } func (tx *LegacyTx) nonce() uint64 { return tx.Nonce }
func (tx *LegacyTx) to() *core.Address { return tx.To } func (tx *LegacyTx) to() *core.Address { return tx.To }
func (tx *LegacyTx) blobGas() uint64 { return 0}
func (tx *LegacyTx) blobGasFeeCap() *big.Int { return nil }
func (tx *LegacyTx) blobHashes() []core.Hash { return nil }
func (tx *LegacyTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int { func (tx *LegacyTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
return dst.Set(tx.GasPrice) return dst.Set(tx.GasPrice)

View File

@ -44,6 +44,7 @@ const (
LegacyTxType = iota LegacyTxType = iota
AccessListTxType AccessListTxType
DynamicFeeTxType DynamicFeeTxType
BlobTxType
) )
// Transaction is an Ethereum transaction. // Transaction is an Ethereum transaction.
@ -86,6 +87,9 @@ type TxData interface {
value() *big.Int value() *big.Int
nonce() uint64 nonce() uint64
to() *core.Address to() *core.Address
blobGas() uint64
blobGasFeeCap() *big.Int
blobHashes() []core.Hash
rawSignatureValues() (v, r, s *big.Int) rawSignatureValues() (v, r, s *big.Int)
setSignatureValues(chainID, v, r, s *big.Int) setSignatureValues(chainID, v, r, s *big.Int)
@ -200,6 +204,10 @@ func (tx *Transaction) decodeTyped(b []byte) (TxData, error) {
var inner DynamicFeeTx var inner DynamicFeeTx
err := rlp.DecodeBytes(b[1:], &inner) err := rlp.DecodeBytes(b[1:], &inner)
return &inner, err return &inner, err
case BlobTxType:
var inner BlobTx
err := rlp.DecodeBytes(b[1:], &inner)
return &inner, err
default: default:
return nil, ErrTxTypeNotSupported return nil, ErrTxTypeNotSupported
} }
@ -295,15 +303,26 @@ func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.inner.value
// Nonce returns the sender account nonce of the transaction. // Nonce returns the sender account nonce of the transaction.
func (tx *Transaction) Nonce() uint64 { return tx.inner.nonce() } func (tx *Transaction) Nonce() uint64 { return tx.inner.nonce() }
// BlobGasFeeCap returns the fee cap per gas of the transaction.
func (tx *Transaction) BlobGasFeeCap() *big.Int { return new(big.Int).Set(tx.inner.blobGasFeeCap()) }
// BlobGas returns the blob gas of the transaction.
func (tx *Transaction) BlobGas() uint64 { return tx.inner.blobGas() }
func (tx *Transaction) BlobHashes() []core.Hash { return tx.inner.blobHashes() }
// To returns the recipient address of the transaction. // To returns the recipient address of the transaction.
// For contract-creation transactions, To returns nil. // For contract-creation transactions, To returns nil.
func (tx *Transaction) To() *core.Address { func (tx *Transaction) To() *core.Address {
return copyAddressPtr(tx.inner.to()) return copyAddressPtr(tx.inner.to())
} }
// Cost returns gas * gasPrice + value. // Cost returns (gas * gasPrice) + (blobGas * blobGasPrice) + value.
func (tx *Transaction) Cost() *big.Int { func (tx *Transaction) Cost() *big.Int {
total := new(big.Int).Mul(tx.GasPrice(), new(big.Int).SetUint64(tx.Gas())) total := new(big.Int).Mul(tx.GasPrice(), new(big.Int).SetUint64(tx.Gas()))
if tx.Type() == BlobTxType {
total.Add(total, new(big.Int).Mul(tx.BlobGasFeeCap(), new(big.Int).SetUint64(tx.BlobGas())))
}
total.Add(total, tx.Value()) total.Add(total, tx.Value())
return total return total
} }