Skip to content

Commit a3bd485

Browse files
authored
Merge pull request #527 from gzliudan/eip1559
implement EIP-1559
2 parents 0454aa3 + 56ed523 commit a3bd485

File tree

129 files changed

+6192
-1763
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

129 files changed

+6192
-1763
lines changed

accounts/abi/bind/backend.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ var (
3232
// have any code associated with it (i.e. suicided).
3333
ErrNoCode = errors.New("no contract code at given address")
3434

35-
// This error is raised when attempting to perform a pending state action
35+
// ErrNoPendingState is raised when attempting to perform a pending state action
3636
// on a backend that doesn't implement PendingContractCaller.
3737
ErrNoPendingState = errors.New("backend does not support pending state")
3838

39-
// This error is returned by WaitDeployed if contract creation leaves an
40-
// empty contract behind.
39+
// ErrNoCodeAfterDeploy is returned by WaitDeployed if contract creation leaves
40+
// an empty contract behind.
4141
ErrNoCodeAfterDeploy = errors.New("no contract code after deployment")
4242
)
4343

@@ -47,7 +47,8 @@ type ContractCaller interface {
4747
// CodeAt returns the code of the given account. This is needed to differentiate
4848
// between contract internal errors and the local chain being out of sync.
4949
CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error)
50-
// ContractCall executes an Ethereum contract call with the specified data as the
50+
51+
// CallContract executes an Ethereum contract call with the specified data as the
5152
// input.
5253
CallContract(ctx context.Context, call XDPoSChain.CallMsg, blockNumber *big.Int) ([]byte, error)
5354
}
@@ -58,6 +59,7 @@ type ContractCaller interface {
5859
type PendingContractCaller interface {
5960
// PendingCodeAt returns the code of the given account in the pending state.
6061
PendingCodeAt(ctx context.Context, contract common.Address) ([]byte, error)
62+
6163
// PendingCallContract executes an Ethereum contract call against the pending state.
6264
PendingCallContract(ctx context.Context, call XDPoSChain.CallMsg) ([]byte, error)
6365
}
@@ -67,19 +69,31 @@ type PendingContractCaller interface {
6769
// used when the user does not provide some needed values, but rather leaves it up
6870
// to the transactor to decide.
6971
type ContractTransactor interface {
72+
// HeaderByNumber returns a block header from the current canonical chain. If
73+
// number is nil, the latest known header is returned.
74+
HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error)
75+
7076
// PendingCodeAt returns the code of the given account in the pending state.
7177
PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error)
78+
7279
// PendingNonceAt retrieves the current pending nonce associated with an account.
7380
PendingNonceAt(ctx context.Context, account common.Address) (uint64, error)
81+
7482
// SuggestGasPrice retrieves the currently suggested gas price to allow a timely
7583
// execution of a transaction.
7684
SuggestGasPrice(ctx context.Context) (*big.Int, error)
85+
86+
// SuggestGasTipCap retrieves the currently suggested 1559 priority fee to allow
87+
// a timely execution of a transaction.
88+
SuggestGasTipCap(ctx context.Context) (*big.Int, error)
89+
7790
// EstimateGas tries to estimate the gas needed to execute a specific
7891
// transaction based on the current pending state of the backend blockchain.
7992
// There is no guarantee that this is the true gas limit requirement as other
8093
// transactions may be added or removed by miners, but it should provide a basis
8194
// for setting a reasonable default.
8295
EstimateGas(ctx context.Context, call XDPoSChain.CallMsg) (gas uint64, err error)
96+
8397
// SendTransaction injects the transaction into the pending pool for execution.
8498
SendTransaction(ctx context.Context, tx *types.Transaction) error
8599
}

accounts/abi/bind/backends/simulated.go

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,19 @@ func (b *SimulatedBackend) TransactionReceipt(ctx context.Context, txHash common
256256
return receipt, nil
257257
}
258258

259+
// HeaderByNumber returns a block header from the current canonical chain. If number is
260+
// nil, the latest known header is returned.
261+
func (b *SimulatedBackend) HeaderByNumber(ctx context.Context, block *big.Int) (*types.Header, error) {
262+
b.mu.Lock()
263+
defer b.mu.Unlock()
264+
265+
if block == nil || block.Cmp(b.pendingBlock.Number()) == 0 {
266+
return b.blockchain.CurrentHeader(), nil
267+
}
268+
269+
return b.blockchain.GetHeaderByNumber(uint64(block.Int64())), nil
270+
}
271+
259272
// PendingCodeAt returns the code associated with an account in the pending state.
260273
func (b *SimulatedBackend) PendingCodeAt(ctx context.Context, contract common.Address) ([]byte, error) {
261274
b.mu.Lock()
@@ -300,8 +313,17 @@ func (b *SimulatedBackend) PendingNonceAt(ctx context.Context, account common.Ad
300313
}
301314

302315
// SuggestGasPrice implements ContractTransactor.SuggestGasPrice. Since the simulated
303-
// chain doens't have miners, we just return a gas price of 1 for any call.
316+
// chain doesn't have miners, we just return a gas price of 1 for any call.
304317
func (b *SimulatedBackend) SuggestGasPrice(ctx context.Context) (*big.Int, error) {
318+
if b.pendingBlock.Header().BaseFee != nil {
319+
return b.pendingBlock.Header().BaseFee, nil
320+
}
321+
return big.NewInt(1), nil
322+
}
323+
324+
// SuggestGasTipCap implements ContractTransactor.SuggestGasTipCap. Since the simulated
325+
// chain doesn't have miners, we just return a gas tip of 1 for any call.
326+
func (b *SimulatedBackend) SuggestGasTipCap(ctx context.Context) (*big.Int, error) {
305327
return big.NewInt(1), nil
306328
}
307329

@@ -358,10 +380,38 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call XDPoSChain.Call
358380
// callContract implements common code between normal and pending contract calls.
359381
// state is modified during execution, make sure to copy it if necessary.
360382
func (b *SimulatedBackend) callContract(ctx context.Context, call XDPoSChain.CallMsg, block *types.Block, statedb *state.StateDB) (ret []byte, usedGas uint64, failed bool, err error) {
361-
// Ensure message is initialized properly.
362-
if call.GasPrice == nil {
363-
call.GasPrice = big.NewInt(1)
383+
// Gas prices post 1559 need to be initialized
384+
if call.GasPrice != nil && (call.GasFeeCap != nil || call.GasTipCap != nil) {
385+
return nil, 0, false, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
386+
}
387+
head := b.blockchain.CurrentHeader()
388+
if !b.blockchain.Config().IsEIP1559(head.Number) {
389+
// If there's no basefee, then it must be a non-1559 execution
390+
if call.GasPrice == nil {
391+
call.GasPrice = new(big.Int)
392+
}
393+
call.GasFeeCap, call.GasTipCap = call.GasPrice, call.GasPrice
394+
} else {
395+
// A basefee is provided, necessitating 1559-type execution
396+
if call.GasPrice != nil {
397+
// User specified the legacy gas field, convert to 1559 gas typing
398+
call.GasFeeCap, call.GasTipCap = call.GasPrice, call.GasPrice
399+
} else {
400+
// User specified 1559 gas feilds (or none), use those
401+
if call.GasFeeCap == nil {
402+
call.GasFeeCap = new(big.Int)
403+
}
404+
if call.GasTipCap == nil {
405+
call.GasTipCap = new(big.Int)
406+
}
407+
// Backfill the legacy gasPrice for EVM execution, unless we're all zeroes
408+
call.GasPrice = new(big.Int)
409+
if call.GasFeeCap.BitLen() > 0 || call.GasTipCap.BitLen() > 0 {
410+
call.GasPrice = math.BigMin(new(big.Int).Add(call.GasTipCap, head.BaseFee), call.GasFeeCap)
411+
}
412+
}
364413
}
414+
// Ensure message is initialized properly.
365415
if call.Gas == 0 {
366416
call.Gas = 50000000
367417
}
@@ -384,7 +434,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call XDPoSChain.Cal
384434
evmContext := core.NewEVMBlockContext(block.Header(), b.blockchain, nil)
385435
// Create a new environment which holds all relevant information
386436
// about the transaction and calling mechanisms.
387-
vmenv := vm.NewEVM(evmContext, txContext, statedb, nil, b.config, vm.Config{})
437+
vmenv := vm.NewEVM(evmContext, txContext, statedb, nil, b.config, vm.Config{NoBaseFee: true})
388438
gaspool := new(core.GasPool).AddGas(math.MaxUint64)
389439
owner := common.Address{}
390440
ret, usedGas, failed, err, _ = core.NewStateTransition(vmenv, msg, gaspool).TransitionDb(owner)
@@ -522,9 +572,11 @@ type callMsg struct {
522572

523573
func (m callMsg) From() common.Address { return m.CallMsg.From }
524574
func (m callMsg) Nonce() uint64 { return 0 }
525-
func (m callMsg) CheckNonce() bool { return false }
575+
func (m callMsg) IsFake() bool { return true }
526576
func (m callMsg) To() *common.Address { return m.CallMsg.To }
527577
func (m callMsg) GasPrice() *big.Int { return m.CallMsg.GasPrice }
578+
func (m callMsg) GasFeeCap() *big.Int { return m.CallMsg.GasFeeCap }
579+
func (m callMsg) GasTipCap() *big.Int { return m.CallMsg.GasTipCap }
528580
func (m callMsg) Gas() uint64 { return m.CallMsg.Gas }
529581
func (m callMsg) Value() *big.Int { return m.CallMsg.Value }
530582
func (m callMsg) Data() []byte { return m.CallMsg.Data }
@@ -554,7 +606,11 @@ func (fb *filterBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*t
554606
}
555607

556608
func (fb *filterBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
557-
return core.GetBlockReceipts(fb.db, hash, core.GetBlockNumber(fb.db, hash)), nil
609+
number := rawdb.ReadHeaderNumber(fb.db, hash)
610+
if number == nil {
611+
return nil, nil
612+
}
613+
return rawdb.ReadReceipts(fb.db, hash, *number, fb.bc.Config()), nil
558614
}
559615

560616
func (fb *filterBackend) GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error) {

0 commit comments

Comments
 (0)