Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EIP1559 #31

Merged
merged 16 commits into from
Nov 5, 2020
46 changes: 23 additions & 23 deletions accounts/abi/bind/backends/simulated.go
Original file line number Diff line number Diff line change
Expand Up @@ -555,23 +555,23 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
// If we have finalized EIP1559 and do not have a properly formed EIP1559 trx, sub in default values
eip1559 := b.config.IsEIP1559(block.Number())
eip1559Finalized := b.config.IsEIP1559Finalized(block.Number())
if eip1559Finalized && (call.GasPremium == nil || call.FeeCap == nil || call.GasPrice != nil) {
call.GasPremium = big.NewInt(1)
call.FeeCap = big.NewInt(10)
if eip1559Finalized && (call.MaxMinerBribePerGas == nil || call.FeeCapPerGas == nil || call.GasPrice != nil) {
call.MaxMinerBribePerGas = big.NewInt(1)
call.FeeCapPerGas = big.NewInt(10)
call.GasPrice = nil
}
// If we have not activated EIP1559 and do not have a properly formed legacy trx, sub in default values
if !eip1559 && (call.GasPremium != nil || call.FeeCap != nil || call.GasPrice == nil) {
call.GasPremium = nil
call.FeeCap = nil
if !eip1559 && (call.MaxMinerBribePerGas != nil || call.FeeCapPerGas != nil || call.GasPrice == nil) {
call.MaxMinerBribePerGas = nil
call.FeeCapPerGas = nil
call.GasPrice = big.NewInt(1)
}
// If we are in between activation and finalization
if eip1559 && !eip1559Finalized {
// and we have neither a properly formed legacy or EIP1559 transaction, sub in default legacy values
if (call.GasPremium == nil || call.FeeCap == nil && call.GasPrice == nil) || (call.GasPremium != nil || call.FeeCap != nil && call.GasPrice != nil) {
call.GasPremium = nil
call.FeeCap = nil
if (call.MaxMinerBribePerGas == nil || call.FeeCapPerGas == nil && call.GasPrice == nil) || (call.MaxMinerBribePerGas != nil || call.FeeCapPerGas != nil && call.GasPrice != nil) {
call.MaxMinerBribePerGas = nil
call.FeeCapPerGas = nil
call.GasPrice = big.NewInt(1)
}
}
Expand Down Expand Up @@ -612,16 +612,16 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa
if eip1559 && b.pendingBlock.BaseFee() == nil {
return core.ErrNoBaseFee
}
if eip1559Finalized && (tx.GasPremium() == nil || tx.FeeCap() == nil || tx.GasPrice() != nil) {
if eip1559Finalized && (tx.MaxMinerBribe() == nil || tx.FeeCap() == nil || tx.GasPrice() != nil) {
return core.ErrTxNotEIP1559
}
if !eip1559 && (tx.GasPremium() != nil || tx.FeeCap() != nil || tx.GasPrice() == nil) {
if !eip1559 && (tx.MaxMinerBribe() != nil || tx.FeeCap() != nil || tx.GasPrice() == nil) {
return core.ErrTxIsEIP1559
}
if tx.GasPrice() != nil && (tx.GasPremium() != nil || tx.FeeCap() != nil) {
if tx.GasPrice() != nil && (tx.MaxMinerBribe() != nil || tx.FeeCap() != nil) {
return core.ErrTxSetsLegacyAndEIP1559Fields
}
if tx.GasPrice() == nil && (tx.GasPremium() == nil || tx.FeeCap() == nil) {
if tx.GasPrice() == nil && (tx.MaxMinerBribe() == nil || tx.FeeCap() == nil) {
return core.ErrMissingGasFields
}

Expand Down Expand Up @@ -771,16 +771,16 @@ type callmsg struct {
ethereum.CallMsg
}

func (m callmsg) From() common.Address { return m.CallMsg.From }
func (m callmsg) Nonce() uint64 { return 0 }
func (m callmsg) CheckNonce() bool { return false }
func (m callmsg) To() *common.Address { return m.CallMsg.To }
func (m callmsg) GasPrice() *big.Int { return m.CallMsg.GasPrice }
func (m callmsg) Gas() uint64 { return m.CallMsg.Gas }
func (m callmsg) Value() *big.Int { return m.CallMsg.Value }
func (m callmsg) Data() []byte { return m.CallMsg.Data }
func (m callmsg) GasPremium() *big.Int { return m.CallMsg.GasPremium }
func (m callmsg) FeeCap() *big.Int { return m.CallMsg.FeeCap }
func (m callmsg) From() common.Address { return m.CallMsg.From }
func (m callmsg) Nonce() uint64 { return 0 }
func (m callmsg) CheckNonce() bool { return false }
func (m callmsg) To() *common.Address { return m.CallMsg.To }
func (m callmsg) GasPrice() *big.Int { return m.CallMsg.GasPrice }
func (m callmsg) Gas() uint64 { return m.CallMsg.Gas }
func (m callmsg) Value() *big.Int { return m.CallMsg.Value }
func (m callmsg) Data() []byte { return m.CallMsg.Data }
func (m callmsg) MaxMinerBribe() *big.Int { return m.CallMsg.MaxMinerBribePerGas }
func (m callmsg) FeeCap() *big.Int { return m.CallMsg.FeeCapPerGas }

// filterBackend implements filters.Backend to support filtering for logs without
// taking bloom-bits acceleration structures into account.
Expand Down
26 changes: 13 additions & 13 deletions accounts/abi/bind/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ type TransactOpts struct {
GasLimit uint64 // Gas limit to set for the transaction execution (0 = estimate)

// If GasPrice, GasPremium, and FeeCap are all nil then we defer to the gas price oracle
GasPrice *big.Int // Gas price to use for the transaction execution
GasPremium *big.Int // Gas premium (tip) to use for EIP1559 transaction execution (
FeeCap *big.Int // Fee cap to use for EIP1559 transaction execution
GasPrice *big.Int // Gas price to use for the transaction execution
MaxMinerBribePerGas *big.Int // Gas premium (tip) to use for EIP1559 transaction execution (
FeeCapPerGas *big.Int // Fee cap to use for EIP1559 transaction execution

Context context.Context // Network context to support cancellation and timeouts (nil = no timeout)
}
Expand Down Expand Up @@ -217,7 +217,7 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i
}
// Figure out the gas allowance and gas price values
gasPrice := opts.GasPrice
if gasPrice == nil && opts.FeeCap == nil && opts.GasPremium == nil {
if gasPrice == nil && opts.FeeCapPerGas == nil && opts.MaxMinerBribePerGas == nil {
gasPrice, err = c.transactor.SuggestGasPrice(ensureContext(opts.Context))
if err != nil {
return nil, fmt.Errorf("failed to suggest gas price: %v", err)
Expand All @@ -235,13 +235,13 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i
}
// If the contract surely has code (or code is not needed), estimate the transaction
msg := ethereum.CallMsg{
From: opts.From,
To: contract,
GasPrice: gasPrice,
Value: value,
Data: input,
GasPremium: opts.GasPremium,
FeeCap: opts.FeeCap,
From: opts.From,
To: contract,
GasPrice: gasPrice,
Value: value,
Data: input,
MaxMinerBribePerGas: opts.MaxMinerBribePerGas,
FeeCapPerGas: opts.FeeCapPerGas,
}
gasLimit, err = c.transactor.EstimateGas(ensureContext(opts.Context), msg)
if err != nil {
Expand All @@ -251,9 +251,9 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i
// Create the transaction, sign it and schedule it for execution
var rawTx *types.Transaction
if contract == nil {
rawTx = types.NewContractCreation(nonce, value, gasLimit, gasPrice, input, opts.GasPremium, opts.FeeCap)
rawTx = types.NewContractCreation(nonce, value, gasLimit, gasPrice, input, opts.MaxMinerBribePerGas, opts.FeeCapPerGas)
} else {
rawTx = types.NewTransaction(nonce, c.address, value, gasLimit, gasPrice, input, opts.GasPremium, opts.FeeCap)
rawTx = types.NewTransaction(nonce, c.address, value, gasLimit, gasPrice, input, opts.MaxMinerBribePerGas, opts.FeeCapPerGas)
}
if opts.Signer == nil {
return nil, errors.New("no signer to authorize the transaction with")
Expand Down
18 changes: 9 additions & 9 deletions accounts/external/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,15 +200,15 @@ func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transactio
to = &t
}
args := &core.SendTxArgs{
Data: &data,
Nonce: hexutil.Uint64(tx.Nonce()),
Value: hexutil.Big(*tx.Value()),
Gas: hexutil.Uint64(tx.Gas()),
GasPrice: (*hexutil.Big)(tx.GasPrice()),
GasPremium: (*hexutil.Big)(tx.GasPremium()),
FeeCap: (*hexutil.Big)(tx.FeeCap()),
To: to,
From: common.NewMixedcaseAddress(account.Address),
Data: &data,
Nonce: hexutil.Uint64(tx.Nonce()),
Value: hexutil.Big(*tx.Value()),
Gas: hexutil.Uint64(tx.Gas()),
GasPrice: (*hexutil.Big)(tx.GasPrice()),
MaxMinerBribePerGas: (*hexutil.Big)(tx.MaxMinerBribe()),
FeeCapPerGas: (*hexutil.Big)(tx.FeeCap()),
To: to,
From: common.NewMixedcaseAddress(account.Address),
}
if err := api.client.Call(&res, "account_signTransaction", args); err != nil {
return nil, err
Expand Down
1 change: 1 addition & 0 deletions cmd/geth/misccmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ func version(ctx *cli.Context) error {
if gitDate != "" {
fmt.Println("Git Commit Date:", gitDate)
}
fmt.Println("EIP1559: 970c594cd3")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should add this info to the version meta in addition to (or instead of) here

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VersionMeta  = "eip1559-970c594cd3"

fmt.Println("Architecture:", runtime.GOARCH)
fmt.Println("Protocol Versions:", eth.ProtocolVersions)
fmt.Println("Go Version:", runtime.Version())
Expand Down
72 changes: 37 additions & 35 deletions consensus/misc/basefee.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package misc

import (
"errors"

"math/big"

"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -59,6 +60,37 @@ func VerifyEIP1559BaseFee(config *params.ChainConfig, header, parent *types.Head
return nil
}

func computeBaseFee(pBaseFee *big.Int, pGasUsed, pGasTarget, denominator uint64) *big.Int {
var baseFee *big.Int
if pGasUsed == pGasTarget {
baseFee = new(big.Int).Set(pBaseFee)
} else if pGasUsed > pGasTarget {
gasDelta := big.NewInt(int64(pGasUsed) - int64(pGasTarget))
feeDelta := math.BigMax(
new(big.Int).Div(
new(big.Int).Mul(pBaseFee, gasDelta),
new(big.Int).Mul(
new(big.Int).SetUint64(pGasTarget),
new(big.Int).SetUint64(denominator),
),
),
big.NewInt(1),
)
baseFee = new(big.Int).Add(pBaseFee, feeDelta)
} else {
gasDelta := big.NewInt(int64(pGasTarget) - int64(pGasUsed))
feeDelta := new(big.Int).Div(
new(big.Int).Mul(pBaseFee, gasDelta),
new(big.Int).Mul(
new(big.Int).SetUint64(pGasTarget),
new(big.Int).SetUint64(denominator),
),
)
baseFee = new(big.Int).Sub(pBaseFee, feeDelta)
}
return baseFee
}

// CalcBaseFee returns the baseFee for the current block provided the parent header and config parameters
func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
height := new(big.Int).Add(parent.Number, common.Big1)
Expand All @@ -73,42 +105,12 @@ func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
return new(big.Int).SetUint64(config.EIP1559.InitialBaseFee)
}

parentBaseFee := parent.BaseFee
parentBlockGasUsed := new(big.Int).SetUint64(parent.GasUsed)
targetGasUsed := new(big.Int).SetUint64(parent.GasLimit)
baseFeeMaxChangeDenominator := new(big.Int).SetUint64(config.EIP1559.EIP1559BaseFeeMaxChangeDenominator)

cmp := parentBlockGasUsed.Cmp(targetGasUsed)

if cmp == 0 {
return targetGasUsed
}

if cmp > 0 {
gasDelta := new(big.Int).Sub(parentBlockGasUsed, targetGasUsed)
feeDelta := math.BigMax(
new(big.Int).Div(
new(big.Int).Div(
new(big.Int).Mul(parentBaseFee, gasDelta),
targetGasUsed,
),
baseFeeMaxChangeDenominator,
),
common.Big1,
)
return new(big.Int).Add(parentBaseFee, feeDelta)
}

gasDelta := new(big.Int).Sub(targetGasUsed, parentBlockGasUsed)
feeDelta := new(big.Int).Div(
new(big.Int).Div(
new(big.Int).Mul(parentBaseFee, gasDelta),
targetGasUsed,
),
baseFeeMaxChangeDenominator,
return computeBaseFee(
parent.BaseFee,
parent.GasUsed,
parent.GasLimit,
config.EIP1559.EIP1559BaseFeeMaxChangeDenominator,
)

return new(big.Int).Sub(parentBaseFee, feeDelta)
}

// CalcEIP1559GasTarget returns the EIP1559GasTarget at the current height and header.GasLimit
Expand Down
32 changes: 13 additions & 19 deletions consensus/misc/basefee_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func TestCalcBaseFee(t *testing.T) {
big.NewInt(1000000000),
1000000,
10000000,
big.NewInt(1125000000),
big.NewInt(2125000000),
},
{
params.EIP1559ChainConfig,
Expand All @@ -165,7 +165,7 @@ func TestCalcBaseFee(t *testing.T) {
big.NewInt(1000000000),
500000,
10000000,
big.NewInt(1125000000),
big.NewInt(3375000000),
},
{
params.EIP1559ChainConfig,
Expand All @@ -175,7 +175,7 @@ func TestCalcBaseFee(t *testing.T) {
big.NewInt(1000000000),
1000000,
10000000,
big.NewInt(1125000000),
big.NewInt(2125000000),
},
{
params.EIP1559ChainConfig,
Expand Down Expand Up @@ -217,15 +217,15 @@ func TestCalcBaseFee(t *testing.T) {
10000000,
big.NewInt(1013888888),
},
{
{ // 10
params.EIP1559ChainConfig,
big.NewInt(1000),
1000,
big.NewInt(2000),
big.NewInt(1000000000),
10000000,
10000000,
big.NewInt(999999999), // baseFee diff is -1 when usage == target
big.NewInt(1000000000), // baseFee diff is -1 when usage == target
},
{
params.EIP1559ChainConfig,
Expand All @@ -235,7 +235,7 @@ func TestCalcBaseFee(t *testing.T) {
big.NewInt(1000000000),
11000000,
10000000,
big.NewInt(988636363),
big.NewInt(988636364),
},
{
params.EIP1559ChainConfig,
Expand All @@ -245,7 +245,7 @@ func TestCalcBaseFee(t *testing.T) {
big.NewInt(900000000),
1000000,
10000000,
big.NewInt(1012500000),
big.NewInt(1912500000),
},
{
params.EIP1559ChainConfig,
Expand All @@ -255,7 +255,7 @@ func TestCalcBaseFee(t *testing.T) {
big.NewInt(1100000000),
1000000,
10000000,
big.NewInt(1237500000),
big.NewInt(2337500000),
},
{
params.EIP1559ChainConfig,
Expand All @@ -265,7 +265,7 @@ func TestCalcBaseFee(t *testing.T) {
big.NewInt(1200000000),
1000000,
10000000,
big.NewInt(1350000000),
big.NewInt(2550000000),
},
{
params.EIP1559ChainConfig,
Expand Down Expand Up @@ -328,7 +328,7 @@ func TestCalcBaseFee(t *testing.T) {
big.NewInt(0),
1000000000000000,
1,
big.NewInt(1),
big.NewInt(0),
},
// parent gas usage == parent gas limit
// parent baseFee == 0
Expand All @@ -355,11 +355,8 @@ func TestCalcBaseFee(t *testing.T) {
big.NewInt(1),
1,
1000000000000000,
big.NewInt(2),
big.NewInt(125000000000000),
},
// parent gas usage <<<< parent gas limit
// parent baseFee == 1
// as expected, decrement by 1
{
params.EIP1559ChainConfig,
big.NewInt(1000),
Expand All @@ -368,11 +365,8 @@ func TestCalcBaseFee(t *testing.T) {
big.NewInt(1),
1000000000000000,
1,
big.NewInt(0),
big.NewInt(1),
},
// parent gas usage == parent gas limit
// parent baseFee == 1
// as expected, decrement by 1 when gas usage equals the gas target
{
params.EIP1559ChainConfig,
big.NewInt(1000),
Expand All @@ -381,7 +375,7 @@ func TestCalcBaseFee(t *testing.T) {
big.NewInt(1),
1,
1,
big.NewInt(0),
big.NewInt(1),
},
}
for i, test := range testConditions {
Expand Down
Loading