all: rename internal 1559 gas fields, add support for graphql (#23010)
* all: rename internal 1559 gas fields, add support for graphql * cmd/evm/testdata, core: use public 1559 gas names on API surfaces
This commit is contained in:
parent
248572ee54
commit
c503f98f6d
@ -716,8 +716,8 @@ func (m callMsg) Nonce() uint64 { return 0 }
|
|||||||
func (m callMsg) CheckNonce() bool { return false }
|
func (m callMsg) CheckNonce() bool { return false }
|
||||||
func (m callMsg) To() *common.Address { return m.CallMsg.To }
|
func (m callMsg) To() *common.Address { return m.CallMsg.To }
|
||||||
func (m callMsg) GasPrice() *big.Int { return m.CallMsg.GasPrice }
|
func (m callMsg) GasPrice() *big.Int { return m.CallMsg.GasPrice }
|
||||||
func (m callMsg) FeeCap() *big.Int { return m.CallMsg.FeeCap }
|
func (m callMsg) GasFeeCap() *big.Int { return m.CallMsg.GasFeeCap }
|
||||||
func (m callMsg) Tip() *big.Int { return m.CallMsg.Tip }
|
func (m callMsg) GasTipCap() *big.Int { return m.CallMsg.GasTipCap }
|
||||||
func (m callMsg) Gas() uint64 { return m.CallMsg.Gas }
|
func (m callMsg) Gas() uint64 { return m.CallMsg.Gas }
|
||||||
func (m callMsg) Value() *big.Int { return m.CallMsg.Value }
|
func (m callMsg) Value() *big.Int { return m.CallMsg.Value }
|
||||||
func (m callMsg) Data() []byte { return m.CallMsg.Data }
|
func (m callMsg) Data() []byte { return m.CallMsg.Data }
|
||||||
|
16
cmd/evm/testdata/10/txs.json
vendored
16
cmd/evm/testdata/10/txs.json
vendored
@ -11,8 +11,8 @@
|
|||||||
"secretKey" : "0x41f6e321b31e72173f8ff2e292359e1862f24fba42fe6f97efaf641980eff298",
|
"secretKey" : "0x41f6e321b31e72173f8ff2e292359e1862f24fba42fe6f97efaf641980eff298",
|
||||||
"chainId" : "0x1",
|
"chainId" : "0x1",
|
||||||
"type" : "0x2",
|
"type" : "0x2",
|
||||||
"feeCap" : "0xfa0",
|
"maxFeePerGas" : "0xfa0",
|
||||||
"tip" : "0x0",
|
"maxPriorityFeePerGas" : "0x0",
|
||||||
"accessList" : [
|
"accessList" : [
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -28,8 +28,8 @@
|
|||||||
"secretKey" : "0x41f6e321b31e72173f8ff2e292359e1862f24fba42fe6f97efaf641980eff298",
|
"secretKey" : "0x41f6e321b31e72173f8ff2e292359e1862f24fba42fe6f97efaf641980eff298",
|
||||||
"chainId" : "0x1",
|
"chainId" : "0x1",
|
||||||
"type" : "0x2",
|
"type" : "0x2",
|
||||||
"feeCap" : "0xfa0",
|
"maxFeePerGas" : "0xfa0",
|
||||||
"tip" : "0x0",
|
"maxPriorityFeePerGas" : "0x0",
|
||||||
"accessList" : [
|
"accessList" : [
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -45,8 +45,8 @@
|
|||||||
"secretKey" : "0x41f6e321b31e72173f8ff2e292359e1862f24fba42fe6f97efaf641980eff298",
|
"secretKey" : "0x41f6e321b31e72173f8ff2e292359e1862f24fba42fe6f97efaf641980eff298",
|
||||||
"chainId" : "0x1",
|
"chainId" : "0x1",
|
||||||
"type" : "0x2",
|
"type" : "0x2",
|
||||||
"feeCap" : "0xfa0",
|
"maxFeePerGas" : "0xfa0",
|
||||||
"tip" : "0x0",
|
"maxPriorityFeePerGas" : "0x0",
|
||||||
"accessList" : [
|
"accessList" : [
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -62,8 +62,8 @@
|
|||||||
"secretKey" : "0x41f6e321b31e72173f8ff2e292359e1862f24fba42fe6f97efaf641980eff298",
|
"secretKey" : "0x41f6e321b31e72173f8ff2e292359e1862f24fba42fe6f97efaf641980eff298",
|
||||||
"chainId" : "0x1",
|
"chainId" : "0x1",
|
||||||
"type" : "0x2",
|
"type" : "0x2",
|
||||||
"feeCap" : "0xfa0",
|
"maxFeePerGas" : "0xfa0",
|
||||||
"tip" : "0x0",
|
"maxPriorityFeePerGas" : "0x0",
|
||||||
"accessList" : [
|
"accessList" : [
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
4
cmd/evm/testdata/9/txs.json
vendored
4
cmd/evm/testdata/9/txs.json
vendored
@ -1,8 +1,8 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"gas": "0x4ef00",
|
"gas": "0x4ef00",
|
||||||
"tip": "0x2",
|
"maxPriorityFeePerGas": "0x2",
|
||||||
"feeCap": "0x12A05F200",
|
"maxFeePerGas": "0x12A05F200",
|
||||||
"chainId": "0x1",
|
"chainId": "0x1",
|
||||||
"input": "0x",
|
"input": "0x",
|
||||||
"nonce": "0x0",
|
"nonce": "0x0",
|
||||||
|
@ -3116,13 +3116,13 @@ func TestEIP2718Transition(t *testing.T) {
|
|||||||
|
|
||||||
// TestEIP1559Transition tests the following:
|
// TestEIP1559Transition tests the following:
|
||||||
//
|
//
|
||||||
// 1. A tranaction whose feeCap is greater than the baseFee is valid.
|
// 1. A transaction whose gasFeeCap is greater than the baseFee is valid.
|
||||||
// 2. Gas accounting for access lists on EIP-1559 transactions is correct.
|
// 2. Gas accounting for access lists on EIP-1559 transactions is correct.
|
||||||
// 3. Only the transaction's tip will be received by the coinbase.
|
// 3. Only the transaction's tip will be received by the coinbase.
|
||||||
// 4. The transaction sender pays for both the tip and baseFee.
|
// 4. The transaction sender pays for both the tip and baseFee.
|
||||||
// 5. The coinbase receives only the partially realized tip when
|
// 5. The coinbase receives only the partially realized tip when
|
||||||
// feeCap - tip < baseFee.
|
// gasFeeCap - gasTipCap < baseFee.
|
||||||
// 6. Legacy transaction behave as expected (e.g. gasPrice = feeCap = tip).
|
// 6. Legacy transaction behave as expected (e.g. gasPrice = gasFeeCap = gasTipCap).
|
||||||
func TestEIP1559Transition(t *testing.T) {
|
func TestEIP1559Transition(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
|
aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
|
||||||
@ -3176,8 +3176,8 @@ func TestEIP1559Transition(t *testing.T) {
|
|||||||
Nonce: 0,
|
Nonce: 0,
|
||||||
To: &aa,
|
To: &aa,
|
||||||
Gas: 30000,
|
Gas: 30000,
|
||||||
FeeCap: newGwei(5),
|
GasFeeCap: newGwei(5),
|
||||||
Tip: big.NewInt(2),
|
GasTipCap: big.NewInt(2),
|
||||||
AccessList: accesses,
|
AccessList: accesses,
|
||||||
Data: []byte{},
|
Data: []byte{},
|
||||||
}
|
}
|
||||||
@ -3212,7 +3212,7 @@ func TestEIP1559Transition(t *testing.T) {
|
|||||||
// 3: Ensure that miner received only the tx's tip.
|
// 3: Ensure that miner received only the tx's tip.
|
||||||
actual := state.GetBalance(block.Coinbase())
|
actual := state.GetBalance(block.Coinbase())
|
||||||
expected := new(big.Int).Add(
|
expected := new(big.Int).Add(
|
||||||
new(big.Int).SetUint64(block.GasUsed()*block.Transactions()[0].Tip().Uint64()),
|
new(big.Int).SetUint64(block.GasUsed()*block.Transactions()[0].GasTipCap().Uint64()),
|
||||||
ethash.ConstantinopleBlockReward,
|
ethash.ConstantinopleBlockReward,
|
||||||
)
|
)
|
||||||
if actual.Cmp(expected) != 0 {
|
if actual.Cmp(expected) != 0 {
|
||||||
@ -3221,7 +3221,7 @@ func TestEIP1559Transition(t *testing.T) {
|
|||||||
|
|
||||||
// 4: Ensure the tx sender paid for the gasUsed * (tip + block baseFee).
|
// 4: Ensure the tx sender paid for the gasUsed * (tip + block baseFee).
|
||||||
actual = new(big.Int).Sub(funds, state.GetBalance(addr1))
|
actual = new(big.Int).Sub(funds, state.GetBalance(addr1))
|
||||||
expected = new(big.Int).SetUint64(block.GasUsed() * (block.Transactions()[0].Tip().Uint64() + block.BaseFee().Uint64()))
|
expected = new(big.Int).SetUint64(block.GasUsed() * (block.Transactions()[0].GasTipCap().Uint64() + block.BaseFee().Uint64()))
|
||||||
if actual.Cmp(expected) != 0 {
|
if actual.Cmp(expected) != 0 {
|
||||||
t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
|
t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
|
||||||
}
|
}
|
||||||
@ -3247,7 +3247,7 @@ func TestEIP1559Transition(t *testing.T) {
|
|||||||
|
|
||||||
block = chain.GetBlockByNumber(2)
|
block = chain.GetBlockByNumber(2)
|
||||||
state, _ = chain.State()
|
state, _ = chain.State()
|
||||||
effectiveTip := block.Transactions()[0].Tip().Uint64() - block.BaseFee().Uint64()
|
effectiveTip := block.Transactions()[0].GasTipCap().Uint64() - block.BaseFee().Uint64()
|
||||||
|
|
||||||
// 6+5: Ensure that miner received only the tx's effective tip.
|
// 6+5: Ensure that miner received only the tx's effective tip.
|
||||||
actual = state.GetBalance(block.Coinbase())
|
actual = state.GetBalance(block.Coinbase())
|
||||||
|
@ -74,17 +74,17 @@ var (
|
|||||||
|
|
||||||
// ErrTipAboveFeeCap is a sanity error to ensure no one is able to specify a
|
// ErrTipAboveFeeCap is a sanity error to ensure no one is able to specify a
|
||||||
// transaction with a tip higher than the total fee cap.
|
// transaction with a tip higher than the total fee cap.
|
||||||
ErrTipAboveFeeCap = errors.New("tip higher than fee cap")
|
ErrTipAboveFeeCap = errors.New("max priority fee per gas higher than max fee per gas")
|
||||||
|
|
||||||
// ErrTipVeryHigh is a sanity error to avoid extremely big numbers specified
|
// ErrTipVeryHigh is a sanity error to avoid extremely big numbers specified
|
||||||
// in the tip field.
|
// in the tip field.
|
||||||
ErrTipVeryHigh = errors.New("tip higher than 2^256-1")
|
ErrTipVeryHigh = errors.New("max priority fee per gas higher than 2^256-1")
|
||||||
|
|
||||||
// ErrFeeCapVeryHigh is a sanity error to avoid extremely big numbers specified
|
// ErrFeeCapVeryHigh is a sanity error to avoid extremely big numbers specified
|
||||||
// in the fee cap field.
|
// in the fee cap field.
|
||||||
ErrFeeCapVeryHigh = errors.New("fee cap higher than 2^256-1")
|
ErrFeeCapVeryHigh = errors.New("max fee per gas higher than 2^256-1")
|
||||||
|
|
||||||
// ErrFeeCapTooLow is returned if the transaction fee cap is less than the
|
// ErrFeeCapTooLow is returned if the transaction fee cap is less than the
|
||||||
// the base fee of the block.
|
// the base fee of the block.
|
||||||
ErrFeeCapTooLow = errors.New("fee cap less than block base fee")
|
ErrFeeCapTooLow = errors.New("max fee per gas less than block base fee")
|
||||||
)
|
)
|
||||||
|
@ -61,14 +61,14 @@ func TestStateProcessorErrors(t *testing.T) {
|
|||||||
tx, _ := types.SignTx(types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, data), signer, testKey)
|
tx, _ := types.SignTx(types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, data), signer, testKey)
|
||||||
return tx
|
return tx
|
||||||
}
|
}
|
||||||
var mkDynamicTx = func(nonce uint64, to common.Address, gasLimit uint64, tip, feeCap *big.Int) *types.Transaction {
|
var mkDynamicTx = func(nonce uint64, to common.Address, gasLimit uint64, gasTipCap, gasFeeCap *big.Int) *types.Transaction {
|
||||||
tx, _ := types.SignTx(types.NewTx(&types.DynamicFeeTx{
|
tx, _ := types.SignTx(types.NewTx(&types.DynamicFeeTx{
|
||||||
Nonce: nonce,
|
Nonce: nonce,
|
||||||
Tip: tip,
|
GasTipCap: gasTipCap,
|
||||||
FeeCap: feeCap,
|
GasFeeCap: gasFeeCap,
|
||||||
Gas: gasLimit,
|
Gas: gasLimit,
|
||||||
To: &to,
|
To: &to,
|
||||||
Value: big.NewInt(0),
|
Value: big.NewInt(0),
|
||||||
}), signer, testKey)
|
}), signer, testKey)
|
||||||
return tx
|
return tx
|
||||||
}
|
}
|
||||||
@ -146,25 +146,25 @@ func TestStateProcessorErrors(t *testing.T) {
|
|||||||
txs: []*types.Transaction{
|
txs: []*types.Transaction{
|
||||||
mkDynamicTx(0, common.Address{}, params.TxGas, big.NewInt(0), big.NewInt(0)),
|
mkDynamicTx(0, common.Address{}, params.TxGas, big.NewInt(0), big.NewInt(0)),
|
||||||
},
|
},
|
||||||
want: "could not apply tx 0 [0xc4ab868fef0c82ae0387b742aee87907f2d0fc528fc6ea0a021459fb0fc4a4a8]: fee cap less than block base fee: address 0x71562b71999873DB5b286dF957af199Ec94617F7, feeCap: 0 baseFee: 875000000",
|
want: "could not apply tx 0 [0xc4ab868fef0c82ae0387b742aee87907f2d0fc528fc6ea0a021459fb0fc4a4a8]: max fee per gas less than block base fee: address 0x71562b71999873DB5b286dF957af199Ec94617F7, maxFeePerGas: 0 baseFee: 875000000",
|
||||||
},
|
},
|
||||||
{ // ErrTipVeryHigh
|
{ // ErrTipVeryHigh
|
||||||
txs: []*types.Transaction{
|
txs: []*types.Transaction{
|
||||||
mkDynamicTx(0, common.Address{}, params.TxGas, tooBigNumber, big.NewInt(1)),
|
mkDynamicTx(0, common.Address{}, params.TxGas, tooBigNumber, big.NewInt(1)),
|
||||||
},
|
},
|
||||||
want: "could not apply tx 0 [0x15b8391b9981f266b32f3ab7da564bbeb3d6c21628364ea9b32a21139f89f712]: tip higher than 2^256-1: address 0x71562b71999873DB5b286dF957af199Ec94617F7, tip bit length: 257",
|
want: "could not apply tx 0 [0x15b8391b9981f266b32f3ab7da564bbeb3d6c21628364ea9b32a21139f89f712]: max priority fee per gas higher than 2^256-1: address 0x71562b71999873DB5b286dF957af199Ec94617F7, maxPriorityFeePerGas bit length: 257",
|
||||||
},
|
},
|
||||||
{ // ErrFeeCapVeryHigh
|
{ // ErrFeeCapVeryHigh
|
||||||
txs: []*types.Transaction{
|
txs: []*types.Transaction{
|
||||||
mkDynamicTx(0, common.Address{}, params.TxGas, big.NewInt(1), tooBigNumber),
|
mkDynamicTx(0, common.Address{}, params.TxGas, big.NewInt(1), tooBigNumber),
|
||||||
},
|
},
|
||||||
want: "could not apply tx 0 [0x48bc299b83fdb345c57478f239e89814bb3063eb4e4b49f3b6057a69255c16bd]: fee cap higher than 2^256-1: address 0x71562b71999873DB5b286dF957af199Ec94617F7, feeCap bit length: 257",
|
want: "could not apply tx 0 [0x48bc299b83fdb345c57478f239e89814bb3063eb4e4b49f3b6057a69255c16bd]: max fee per gas higher than 2^256-1: address 0x71562b71999873DB5b286dF957af199Ec94617F7, maxFeePerGas bit length: 257",
|
||||||
},
|
},
|
||||||
{ // ErrTipAboveFeeCap
|
{ // ErrTipAboveFeeCap
|
||||||
txs: []*types.Transaction{
|
txs: []*types.Transaction{
|
||||||
mkDynamicTx(0, common.Address{}, params.TxGas, big.NewInt(2), big.NewInt(1)),
|
mkDynamicTx(0, common.Address{}, params.TxGas, big.NewInt(2), big.NewInt(1)),
|
||||||
},
|
},
|
||||||
want: "could not apply tx 0 [0xf987a31ff0c71895780a7612f965a0c8b056deb54e020bb44fa478092f14c9b4]: tip higher than fee cap: address 0x71562b71999873DB5b286dF957af199Ec94617F7, tip: 1, feeCap: 2",
|
want: "could not apply tx 0 [0xf987a31ff0c71895780a7612f965a0c8b056deb54e020bb44fa478092f14c9b4]: max priority fee per gas higher than max fee per gas: address 0x71562b71999873DB5b286dF957af199Ec94617F7, maxPriorityFeePerGas: 2, maxFeePerGas: 1",
|
||||||
},
|
},
|
||||||
{ // ErrInsufficientFunds
|
{ // ErrInsufficientFunds
|
||||||
// Available balance: 1000000000000000000
|
// Available balance: 1000000000000000000
|
||||||
|
@ -50,8 +50,8 @@ type StateTransition struct {
|
|||||||
msg Message
|
msg Message
|
||||||
gas uint64
|
gas uint64
|
||||||
gasPrice *big.Int
|
gasPrice *big.Int
|
||||||
feeCap *big.Int
|
gasFeeCap *big.Int
|
||||||
tip *big.Int
|
gasTipCap *big.Int
|
||||||
initialGas uint64
|
initialGas uint64
|
||||||
value *big.Int
|
value *big.Int
|
||||||
data []byte
|
data []byte
|
||||||
@ -65,8 +65,8 @@ type Message interface {
|
|||||||
To() *common.Address
|
To() *common.Address
|
||||||
|
|
||||||
GasPrice() *big.Int
|
GasPrice() *big.Int
|
||||||
FeeCap() *big.Int
|
GasFeeCap() *big.Int
|
||||||
Tip() *big.Int
|
GasTipCap() *big.Int
|
||||||
Gas() uint64
|
Gas() uint64
|
||||||
Value() *big.Int
|
Value() *big.Int
|
||||||
|
|
||||||
@ -155,15 +155,15 @@ func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation b
|
|||||||
// NewStateTransition initialises and returns a new state transition object.
|
// NewStateTransition initialises and returns a new state transition object.
|
||||||
func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition {
|
func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition {
|
||||||
return &StateTransition{
|
return &StateTransition{
|
||||||
gp: gp,
|
gp: gp,
|
||||||
evm: evm,
|
evm: evm,
|
||||||
msg: msg,
|
msg: msg,
|
||||||
gasPrice: msg.GasPrice(),
|
gasPrice: msg.GasPrice(),
|
||||||
feeCap: msg.FeeCap(),
|
gasFeeCap: msg.GasFeeCap(),
|
||||||
tip: msg.Tip(),
|
gasTipCap: msg.GasTipCap(),
|
||||||
value: msg.Value(),
|
value: msg.Value(),
|
||||||
data: msg.Data(),
|
data: msg.Data(),
|
||||||
state: evm.StateDB,
|
state: evm.StateDB,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,9 +190,9 @@ func (st *StateTransition) buyGas() error {
|
|||||||
mgval := new(big.Int).SetUint64(st.msg.Gas())
|
mgval := new(big.Int).SetUint64(st.msg.Gas())
|
||||||
mgval = mgval.Mul(mgval, st.gasPrice)
|
mgval = mgval.Mul(mgval, st.gasPrice)
|
||||||
balanceCheck := mgval
|
balanceCheck := mgval
|
||||||
if st.feeCap != nil {
|
if st.gasFeeCap != nil {
|
||||||
balanceCheck = new(big.Int).SetUint64(st.msg.Gas())
|
balanceCheck = new(big.Int).SetUint64(st.msg.Gas())
|
||||||
balanceCheck = balanceCheck.Mul(balanceCheck, st.feeCap)
|
balanceCheck = balanceCheck.Mul(balanceCheck, st.gasFeeCap)
|
||||||
}
|
}
|
||||||
if have, want := st.state.GetBalance(st.msg.From()), balanceCheck; have.Cmp(want) < 0 {
|
if have, want := st.state.GetBalance(st.msg.From()), balanceCheck; have.Cmp(want) < 0 {
|
||||||
return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From().Hex(), have, want)
|
return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From().Hex(), have, want)
|
||||||
@ -219,25 +219,25 @@ func (st *StateTransition) preCheck() error {
|
|||||||
st.msg.From().Hex(), msgNonce, stNonce)
|
st.msg.From().Hex(), msgNonce, stNonce)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Make sure that transaction feeCap is greater than the baseFee (post london)
|
// Make sure that transaction gasFeeCap is greater than the baseFee (post london)
|
||||||
if st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) {
|
if st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) {
|
||||||
if l := st.feeCap.BitLen(); l > 256 {
|
if l := st.gasFeeCap.BitLen(); l > 256 {
|
||||||
return fmt.Errorf("%w: address %v, feeCap bit length: %d", ErrFeeCapVeryHigh,
|
return fmt.Errorf("%w: address %v, maxFeePerGas bit length: %d", ErrFeeCapVeryHigh,
|
||||||
st.msg.From().Hex(), l)
|
st.msg.From().Hex(), l)
|
||||||
}
|
}
|
||||||
if l := st.tip.BitLen(); l > 256 {
|
if l := st.gasTipCap.BitLen(); l > 256 {
|
||||||
return fmt.Errorf("%w: address %v, tip bit length: %d", ErrTipVeryHigh,
|
return fmt.Errorf("%w: address %v, maxPriorityFeePerGas bit length: %d", ErrTipVeryHigh,
|
||||||
st.msg.From().Hex(), l)
|
st.msg.From().Hex(), l)
|
||||||
}
|
}
|
||||||
if st.feeCap.Cmp(st.tip) < 0 {
|
if st.gasFeeCap.Cmp(st.gasTipCap) < 0 {
|
||||||
return fmt.Errorf("%w: address %v, tip: %s, feeCap: %s", ErrTipAboveFeeCap,
|
return fmt.Errorf("%w: address %v, maxPriorityFeePerGas: %s, maxFeePerGas: %s", ErrTipAboveFeeCap,
|
||||||
st.msg.From().Hex(), st.feeCap, st.tip)
|
st.msg.From().Hex(), st.gasTipCap, st.gasFeeCap)
|
||||||
}
|
}
|
||||||
// This will panic if baseFee is nil, but basefee presence is verified
|
// This will panic if baseFee is nil, but basefee presence is verified
|
||||||
// as part of header validation.
|
// as part of header validation.
|
||||||
if st.feeCap.Cmp(st.evm.Context.BaseFee) < 0 {
|
if st.gasFeeCap.Cmp(st.evm.Context.BaseFee) < 0 {
|
||||||
return fmt.Errorf("%w: address %v, feeCap: %s baseFee: %s", ErrFeeCapTooLow,
|
return fmt.Errorf("%w: address %v, maxFeePerGas: %s baseFee: %s", ErrFeeCapTooLow,
|
||||||
st.msg.From().Hex(), st.feeCap, st.evm.Context.BaseFee)
|
st.msg.From().Hex(), st.gasFeeCap, st.evm.Context.BaseFee)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return st.buyGas()
|
return st.buyGas()
|
||||||
@ -317,7 +317,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
|
|||||||
}
|
}
|
||||||
effectiveTip := st.gasPrice
|
effectiveTip := st.gasPrice
|
||||||
if st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) {
|
if st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) {
|
||||||
effectiveTip = cmath.BigMin(st.tip, new(big.Int).Sub(st.feeCap, st.evm.Context.BaseFee))
|
effectiveTip = cmath.BigMin(st.gasTipCap, new(big.Int).Sub(st.gasFeeCap, st.evm.Context.BaseFee))
|
||||||
}
|
}
|
||||||
st.state.AddBalance(st.evm.Context.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), effectiveTip))
|
st.state.AddBalance(st.evm.Context.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), effectiveTip))
|
||||||
|
|
||||||
|
@ -280,13 +280,13 @@ func (l *txList) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Tran
|
|||||||
// If there's an older better transaction, abort
|
// If there's an older better transaction, abort
|
||||||
old := l.txs.Get(tx.Nonce())
|
old := l.txs.Get(tx.Nonce())
|
||||||
if old != nil {
|
if old != nil {
|
||||||
if old.FeeCapCmp(tx) >= 0 || old.TipCmp(tx) >= 0 {
|
if old.GasFeeCapCmp(tx) >= 0 || old.GasTipCapCmp(tx) >= 0 {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
// thresholdFeeCap = oldFC * (100 + priceBump) / 100
|
// thresholdFeeCap = oldFC * (100 + priceBump) / 100
|
||||||
a := big.NewInt(100 + int64(priceBump))
|
a := big.NewInt(100 + int64(priceBump))
|
||||||
aFeeCap := new(big.Int).Mul(a, old.FeeCap())
|
aFeeCap := new(big.Int).Mul(a, old.GasFeeCap())
|
||||||
aTip := a.Mul(a, old.Tip())
|
aTip := a.Mul(a, old.GasTipCap())
|
||||||
|
|
||||||
// thresholdTip = oldTip * (100 + priceBump) / 100
|
// thresholdTip = oldTip * (100 + priceBump) / 100
|
||||||
b := big.NewInt(100)
|
b := big.NewInt(100)
|
||||||
@ -296,7 +296,7 @@ func (l *txList) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Tran
|
|||||||
// Have to ensure that either the new fee cap or tip is higher than the
|
// Have to ensure that either the new fee cap or tip is higher than the
|
||||||
// old ones as well as checking the percentage threshold to ensure that
|
// old ones as well as checking the percentage threshold to ensure that
|
||||||
// this is accurate for low (Wei-level) gas price replacements
|
// this is accurate for low (Wei-level) gas price replacements
|
||||||
if tx.FeeCapIntCmp(thresholdFeeCap) < 0 || tx.TipIntCmp(thresholdTip) < 0 {
|
if tx.GasFeeCapIntCmp(thresholdFeeCap) < 0 || tx.GasTipCapIntCmp(thresholdTip) < 0 {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -417,7 +417,7 @@ func (l *txList) LastElement() *types.Transaction {
|
|||||||
// priceHeap is a heap.Interface implementation over transactions for retrieving
|
// priceHeap is a heap.Interface implementation over transactions for retrieving
|
||||||
// price-sorted transactions to discard when the pool fills up. If baseFee is set
|
// price-sorted transactions to discard when the pool fills up. If baseFee is set
|
||||||
// then the heap is sorted based on the effective tip based on the given base fee.
|
// then the heap is sorted based on the effective tip based on the given base fee.
|
||||||
// If baseFee is nil then the sorting is based on feeCap.
|
// If baseFee is nil then the sorting is based on gasFeeCap.
|
||||||
type priceHeap struct {
|
type priceHeap struct {
|
||||||
baseFee *big.Int // heap should always be re-sorted after baseFee is changed
|
baseFee *big.Int // heap should always be re-sorted after baseFee is changed
|
||||||
list []*types.Transaction
|
list []*types.Transaction
|
||||||
@ -440,16 +440,16 @@ func (h *priceHeap) Less(i, j int) bool {
|
|||||||
func (h *priceHeap) cmp(a, b *types.Transaction) int {
|
func (h *priceHeap) cmp(a, b *types.Transaction) int {
|
||||||
if h.baseFee != nil {
|
if h.baseFee != nil {
|
||||||
// Compare effective tips if baseFee is specified
|
// Compare effective tips if baseFee is specified
|
||||||
if c := a.EffectiveTipCmp(b, h.baseFee); c != 0 {
|
if c := a.EffectiveGasTipCmp(b, h.baseFee); c != 0 {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Compare fee caps if baseFee is not specified or effective tips are equal
|
// Compare fee caps if baseFee is not specified or effective tips are equal
|
||||||
if c := a.FeeCapCmp(b); c != 0 {
|
if c := a.GasFeeCapCmp(b); c != 0 {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
// Compare tips if effective tips and fee caps are equal
|
// Compare tips if effective tips and fee caps are equal
|
||||||
return a.TipCmp(b)
|
return a.GasTipCapCmp(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *priceHeap) Push(x interface{}) {
|
func (h *priceHeap) Push(x interface{}) {
|
||||||
@ -472,7 +472,7 @@ func (h *priceHeap) Pop() interface{} {
|
|||||||
// will be considered for tracking, sorting, eviction, etc.
|
// will be considered for tracking, sorting, eviction, etc.
|
||||||
//
|
//
|
||||||
// Two heaps are used for sorting: the urgent heap (based on effective tip in the next
|
// Two heaps are used for sorting: the urgent heap (based on effective tip in the next
|
||||||
// block) and the floating heap (based on feeCap). Always the bigger heap is chosen for
|
// block) and the floating heap (based on gasFeeCap). Always the bigger heap is chosen for
|
||||||
// eviction. Transactions evicted from the urgent heap are first demoted into the floating heap.
|
// eviction. Transactions evicted from the urgent heap are first demoted into the floating heap.
|
||||||
// In some cases (during a congestion, when blocks are full) the urgent heap can provide
|
// In some cases (during a congestion, when blocks are full) the urgent heap can provide
|
||||||
// better candidates for inclusion while in other cases (at the top of the baseFee peak)
|
// better candidates for inclusion while in other cases (at the top of the baseFee peak)
|
||||||
|
@ -434,7 +434,7 @@ func (pool *TxPool) SetGasPrice(price *big.Int) {
|
|||||||
pool.gasPrice = price
|
pool.gasPrice = price
|
||||||
// if the min miner fee increased, remove transactions below the new threshold
|
// if the min miner fee increased, remove transactions below the new threshold
|
||||||
if price.Cmp(old) > 0 {
|
if price.Cmp(old) > 0 {
|
||||||
// pool.priced is sorted by FeeCap, so we have to iterate through pool.all instead
|
// pool.priced is sorted by GasFeeCap, so we have to iterate through pool.all instead
|
||||||
drop := pool.all.RemotesBelowTip(price)
|
drop := pool.all.RemotesBelowTip(price)
|
||||||
for _, tx := range drop {
|
for _, tx := range drop {
|
||||||
pool.removeTx(tx.Hash(), false)
|
pool.removeTx(tx.Hash(), false)
|
||||||
@ -574,14 +574,14 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
|
|||||||
return ErrGasLimit
|
return ErrGasLimit
|
||||||
}
|
}
|
||||||
// Sanity check for extremely large numbers
|
// Sanity check for extremely large numbers
|
||||||
if tx.FeeCap().BitLen() > 256 {
|
if tx.GasFeeCap().BitLen() > 256 {
|
||||||
return ErrFeeCapVeryHigh
|
return ErrFeeCapVeryHigh
|
||||||
}
|
}
|
||||||
if tx.Tip().BitLen() > 256 {
|
if tx.GasTipCap().BitLen() > 256 {
|
||||||
return ErrTipVeryHigh
|
return ErrTipVeryHigh
|
||||||
}
|
}
|
||||||
// Ensure feeCap is greater than or equal to tip.
|
// Ensure gasFeeCap is greater than or equal to gasTipCap.
|
||||||
if tx.FeeCapIntCmp(tx.Tip()) < 0 {
|
if tx.GasFeeCapIntCmp(tx.GasTipCap()) < 0 {
|
||||||
return ErrTipAboveFeeCap
|
return ErrTipAboveFeeCap
|
||||||
}
|
}
|
||||||
// Make sure the transaction is signed properly.
|
// Make sure the transaction is signed properly.
|
||||||
@ -590,7 +590,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
|
|||||||
return ErrInvalidSender
|
return ErrInvalidSender
|
||||||
}
|
}
|
||||||
// Drop non-local transactions under our own minimal accepted gas price or tip
|
// Drop non-local transactions under our own minimal accepted gas price or tip
|
||||||
if !local && tx.TipIntCmp(pool.gasPrice) < 0 {
|
if !local && tx.GasTipCapIntCmp(pool.gasPrice) < 0 {
|
||||||
return ErrUnderpriced
|
return ErrUnderpriced
|
||||||
}
|
}
|
||||||
// Ensure the transaction adheres to nonce ordering
|
// Ensure the transaction adheres to nonce ordering
|
||||||
@ -642,7 +642,7 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e
|
|||||||
if uint64(pool.all.Slots()+numSlots(tx)) > pool.config.GlobalSlots+pool.config.GlobalQueue {
|
if uint64(pool.all.Slots()+numSlots(tx)) > pool.config.GlobalSlots+pool.config.GlobalQueue {
|
||||||
// If the new transaction is underpriced, don't accept it
|
// If the new transaction is underpriced, don't accept it
|
||||||
if !isLocal && pool.priced.Underpriced(tx) {
|
if !isLocal && pool.priced.Underpriced(tx) {
|
||||||
log.Trace("Discarding underpriced transaction", "hash", hash, "tip", tx.Tip(), "feeCap", tx.FeeCap())
|
log.Trace("Discarding underpriced transaction", "hash", hash, "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap())
|
||||||
underpricedTxMeter.Mark(1)
|
underpricedTxMeter.Mark(1)
|
||||||
return false, ErrUnderpriced
|
return false, ErrUnderpriced
|
||||||
}
|
}
|
||||||
@ -659,7 +659,7 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e
|
|||||||
}
|
}
|
||||||
// Kick out the underpriced remote transactions.
|
// Kick out the underpriced remote transactions.
|
||||||
for _, tx := range drop {
|
for _, tx := range drop {
|
||||||
log.Trace("Discarding freshly underpriced transaction", "hash", tx.Hash(), "tip", tx.Tip(), "feeCap", tx.FeeCap())
|
log.Trace("Discarding freshly underpriced transaction", "hash", tx.Hash(), "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap())
|
||||||
underpricedTxMeter.Mark(1)
|
underpricedTxMeter.Mark(1)
|
||||||
pool.removeTx(tx.Hash(), false)
|
pool.removeTx(tx.Hash(), false)
|
||||||
}
|
}
|
||||||
@ -1765,7 +1765,7 @@ func (t *txLookup) RemoteToLocals(locals *accountSet) int {
|
|||||||
func (t *txLookup) RemotesBelowTip(threshold *big.Int) types.Transactions {
|
func (t *txLookup) RemotesBelowTip(threshold *big.Int) types.Transactions {
|
||||||
found := make(types.Transactions, 0, 128)
|
found := make(types.Transactions, 0, 128)
|
||||||
t.Range(func(hash common.Hash, tx *types.Transaction, local bool) bool {
|
t.Range(func(hash common.Hash, tx *types.Transaction, local bool) bool {
|
||||||
if tx.TipIntCmp(threshold) < 0 {
|
if tx.GasTipCapIntCmp(threshold) < 0 {
|
||||||
found = append(found, tx)
|
found = append(found, tx)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
@ -101,8 +101,8 @@ func dynamicFeeTx(nonce uint64, gaslimit uint64, gasFee *big.Int, tip *big.Int,
|
|||||||
tx, _ := types.SignNewTx(key, types.LatestSignerForChainID(params.TestChainConfig.ChainID), &types.DynamicFeeTx{
|
tx, _ := types.SignNewTx(key, types.LatestSignerForChainID(params.TestChainConfig.ChainID), &types.DynamicFeeTx{
|
||||||
ChainID: params.TestChainConfig.ChainID,
|
ChainID: params.TestChainConfig.ChainID,
|
||||||
Nonce: nonce,
|
Nonce: nonce,
|
||||||
Tip: tip,
|
GasTipCap: tip,
|
||||||
FeeCap: gasFee,
|
GasFeeCap: gasFee,
|
||||||
Gas: gaslimit,
|
Gas: gaslimit,
|
||||||
To: &common.Address{},
|
To: &common.Address{},
|
||||||
Value: big.NewInt(100),
|
Value: big.NewInt(100),
|
||||||
@ -2141,17 +2141,17 @@ func TestTransactionReplacementDynamicFee(t *testing.T) {
|
|||||||
defer sub.Unsubscribe()
|
defer sub.Unsubscribe()
|
||||||
|
|
||||||
// Add pending transactions, ensuring the minimum price bump is enforced for replacement (for ultra low prices too)
|
// Add pending transactions, ensuring the minimum price bump is enforced for replacement (for ultra low prices too)
|
||||||
feeCap := int64(100)
|
gasFeeCap := int64(100)
|
||||||
feeCapThreshold := (feeCap * (100 + int64(testTxPoolConfig.PriceBump))) / 100
|
feeCapThreshold := (gasFeeCap * (100 + int64(testTxPoolConfig.PriceBump))) / 100
|
||||||
tip := int64(60)
|
gasTipCap := int64(60)
|
||||||
tipThreshold := (tip * (100 + int64(testTxPoolConfig.PriceBump))) / 100
|
tipThreshold := (gasTipCap * (100 + int64(testTxPoolConfig.PriceBump))) / 100
|
||||||
|
|
||||||
// Run the following identical checks for both the pending and queue pools:
|
// Run the following identical checks for both the pending and queue pools:
|
||||||
// 1. Send initial tx => accept
|
// 1. Send initial tx => accept
|
||||||
// 2. Don't bump tip or fee cap => discard
|
// 2. Don't bump tip or fee cap => discard
|
||||||
// 3. Bump both more than min => accept
|
// 3. Bump both more than min => accept
|
||||||
// 4. Check events match expected (2 new executable txs during pending, 0 during queue)
|
// 4. Check events match expected (2 new executable txs during pending, 0 during queue)
|
||||||
// 5. Send new tx with larger tip and feeCap => accept
|
// 5. Send new tx with larger tip and gasFeeCap => accept
|
||||||
// 6. Bump tip max allowed so it's still underpriced => discard
|
// 6. Bump tip max allowed so it's still underpriced => discard
|
||||||
// 7. Bump fee cap max allowed so it's still underpriced => discard
|
// 7. Bump fee cap max allowed so it's still underpriced => discard
|
||||||
// 8. Bump tip min for acceptance => discard
|
// 8. Bump tip min for acceptance => discard
|
||||||
@ -2191,27 +2191,27 @@ func TestTransactionReplacementDynamicFee(t *testing.T) {
|
|||||||
t.Fatalf("cheap %s replacement event firing failed: %v", stage, err)
|
t.Fatalf("cheap %s replacement event firing failed: %v", stage, err)
|
||||||
}
|
}
|
||||||
// 5. Send new tx with larger tip and feeCap => accept
|
// 5. Send new tx with larger tip and feeCap => accept
|
||||||
tx = dynamicFeeTx(nonce, 100000, big.NewInt(feeCap), big.NewInt(tip), key)
|
tx = dynamicFeeTx(nonce, 100000, big.NewInt(gasFeeCap), big.NewInt(gasTipCap), key)
|
||||||
if err := pool.addRemoteSync(tx); err != nil {
|
if err := pool.addRemoteSync(tx); err != nil {
|
||||||
t.Fatalf("failed to add original proper %s transaction: %v", stage, err)
|
t.Fatalf("failed to add original proper %s transaction: %v", stage, err)
|
||||||
}
|
}
|
||||||
// 6. Bump tip max allowed so it's still underpriced => discard
|
// 6. Bump tip max allowed so it's still underpriced => discard
|
||||||
tx = dynamicFeeTx(nonce, 100000, big.NewInt(feeCap), big.NewInt(tipThreshold-1), key)
|
tx = dynamicFeeTx(nonce, 100000, big.NewInt(gasFeeCap), big.NewInt(tipThreshold-1), key)
|
||||||
if err := pool.AddRemote(tx); err != ErrReplaceUnderpriced {
|
if err := pool.AddRemote(tx); err != ErrReplaceUnderpriced {
|
||||||
t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, ErrReplaceUnderpriced)
|
t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, ErrReplaceUnderpriced)
|
||||||
}
|
}
|
||||||
// 7. Bump fee cap max allowed so it's still underpriced => discard
|
// 7. Bump fee cap max allowed so it's still underpriced => discard
|
||||||
tx = dynamicFeeTx(nonce, 100000, big.NewInt(feeCapThreshold-1), big.NewInt(tip), key)
|
tx = dynamicFeeTx(nonce, 100000, big.NewInt(feeCapThreshold-1), big.NewInt(gasTipCap), key)
|
||||||
if err := pool.AddRemote(tx); err != ErrReplaceUnderpriced {
|
if err := pool.AddRemote(tx); err != ErrReplaceUnderpriced {
|
||||||
t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, ErrReplaceUnderpriced)
|
t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, ErrReplaceUnderpriced)
|
||||||
}
|
}
|
||||||
// 8. Bump tip min for acceptance => accept
|
// 8. Bump tip min for acceptance => accept
|
||||||
tx = dynamicFeeTx(nonce, 100000, big.NewInt(feeCap), big.NewInt(tipThreshold), key)
|
tx = dynamicFeeTx(nonce, 100000, big.NewInt(gasFeeCap), big.NewInt(tipThreshold), key)
|
||||||
if err := pool.AddRemote(tx); err != ErrReplaceUnderpriced {
|
if err := pool.AddRemote(tx); err != ErrReplaceUnderpriced {
|
||||||
t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, ErrReplaceUnderpriced)
|
t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, ErrReplaceUnderpriced)
|
||||||
}
|
}
|
||||||
// 9. Bump fee cap min for acceptance => accept
|
// 9. Bump fee cap min for acceptance => accept
|
||||||
tx = dynamicFeeTx(nonce, 100000, big.NewInt(feeCapThreshold), big.NewInt(tip), key)
|
tx = dynamicFeeTx(nonce, 100000, big.NewInt(feeCapThreshold), big.NewInt(gasTipCap), key)
|
||||||
if err := pool.AddRemote(tx); err != ErrReplaceUnderpriced {
|
if err := pool.AddRemote(tx); err != ErrReplaceUnderpriced {
|
||||||
t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, ErrReplaceUnderpriced)
|
t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, ErrReplaceUnderpriced)
|
||||||
}
|
}
|
||||||
|
@ -101,8 +101,8 @@ func (tx *AccessListTx) accessList() AccessList { return tx.AccessList }
|
|||||||
func (tx *AccessListTx) data() []byte { return tx.Data }
|
func (tx *AccessListTx) data() []byte { return tx.Data }
|
||||||
func (tx *AccessListTx) gas() uint64 { return tx.Gas }
|
func (tx *AccessListTx) gas() uint64 { return tx.Gas }
|
||||||
func (tx *AccessListTx) gasPrice() *big.Int { return tx.GasPrice }
|
func (tx *AccessListTx) gasPrice() *big.Int { return tx.GasPrice }
|
||||||
func (tx *AccessListTx) tip() *big.Int { return tx.GasPrice }
|
func (tx *AccessListTx) gasTipCap() *big.Int { return tx.GasPrice }
|
||||||
func (tx *AccessListTx) feeCap() *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) 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() *common.Address { return tx.To }
|
func (tx *AccessListTx) to() *common.Address { return tx.To }
|
||||||
|
@ -109,8 +109,8 @@ func TestEIP1559BlockEncoding(t *testing.T) {
|
|||||||
Nonce: 0,
|
Nonce: 0,
|
||||||
To: &to,
|
To: &to,
|
||||||
Gas: 123457,
|
Gas: 123457,
|
||||||
FeeCap: new(big.Int).Set(block.BaseFee()),
|
GasFeeCap: new(big.Int).Set(block.BaseFee()),
|
||||||
Tip: big.NewInt(0),
|
GasTipCap: big.NewInt(0),
|
||||||
AccessList: accesses,
|
AccessList: accesses,
|
||||||
Data: []byte{},
|
Data: []byte{},
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,8 @@ import (
|
|||||||
type DynamicFeeTx struct {
|
type DynamicFeeTx struct {
|
||||||
ChainID *big.Int
|
ChainID *big.Int
|
||||||
Nonce uint64
|
Nonce uint64
|
||||||
Tip *big.Int
|
GasTipCap *big.Int
|
||||||
FeeCap *big.Int
|
GasFeeCap *big.Int
|
||||||
Gas uint64
|
Gas uint64
|
||||||
To *common.Address `rlp:"nil"` // nil means contract creation
|
To *common.Address `rlp:"nil"` // nil means contract creation
|
||||||
Value *big.Int
|
Value *big.Int
|
||||||
@ -50,8 +50,8 @@ func (tx *DynamicFeeTx) copy() TxData {
|
|||||||
AccessList: make(AccessList, len(tx.AccessList)),
|
AccessList: make(AccessList, len(tx.AccessList)),
|
||||||
Value: new(big.Int),
|
Value: new(big.Int),
|
||||||
ChainID: new(big.Int),
|
ChainID: new(big.Int),
|
||||||
Tip: new(big.Int),
|
GasTipCap: new(big.Int),
|
||||||
FeeCap: new(big.Int),
|
GasFeeCap: new(big.Int),
|
||||||
V: new(big.Int),
|
V: new(big.Int),
|
||||||
R: new(big.Int),
|
R: new(big.Int),
|
||||||
S: new(big.Int),
|
S: new(big.Int),
|
||||||
@ -63,11 +63,11 @@ func (tx *DynamicFeeTx) copy() TxData {
|
|||||||
if tx.ChainID != nil {
|
if tx.ChainID != nil {
|
||||||
cpy.ChainID.Set(tx.ChainID)
|
cpy.ChainID.Set(tx.ChainID)
|
||||||
}
|
}
|
||||||
if tx.Tip != nil {
|
if tx.GasTipCap != nil {
|
||||||
cpy.Tip.Set(tx.Tip)
|
cpy.GasTipCap.Set(tx.GasTipCap)
|
||||||
}
|
}
|
||||||
if tx.FeeCap != nil {
|
if tx.GasFeeCap != nil {
|
||||||
cpy.FeeCap.Set(tx.FeeCap)
|
cpy.GasFeeCap.Set(tx.GasFeeCap)
|
||||||
}
|
}
|
||||||
if tx.V != nil {
|
if tx.V != nil {
|
||||||
cpy.V.Set(tx.V)
|
cpy.V.Set(tx.V)
|
||||||
@ -88,9 +88,9 @@ func (tx *DynamicFeeTx) protected() bool { return true }
|
|||||||
func (tx *DynamicFeeTx) accessList() AccessList { return tx.AccessList }
|
func (tx *DynamicFeeTx) accessList() AccessList { return tx.AccessList }
|
||||||
func (tx *DynamicFeeTx) data() []byte { return tx.Data }
|
func (tx *DynamicFeeTx) data() []byte { return tx.Data }
|
||||||
func (tx *DynamicFeeTx) gas() uint64 { return tx.Gas }
|
func (tx *DynamicFeeTx) gas() uint64 { return tx.Gas }
|
||||||
func (tx *DynamicFeeTx) feeCap() *big.Int { return tx.FeeCap }
|
func (tx *DynamicFeeTx) gasFeeCap() *big.Int { return tx.GasFeeCap }
|
||||||
func (tx *DynamicFeeTx) tip() *big.Int { return tx.Tip }
|
func (tx *DynamicFeeTx) gasTipCap() *big.Int { return tx.GasTipCap }
|
||||||
func (tx *DynamicFeeTx) gasPrice() *big.Int { return tx.FeeCap }
|
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() *common.Address { return tx.To }
|
func (tx *DynamicFeeTx) to() *common.Address { return tx.To }
|
||||||
|
@ -97,8 +97,8 @@ func (tx *LegacyTx) accessList() AccessList { return nil }
|
|||||||
func (tx *LegacyTx) data() []byte { return tx.Data }
|
func (tx *LegacyTx) data() []byte { return tx.Data }
|
||||||
func (tx *LegacyTx) gas() uint64 { return tx.Gas }
|
func (tx *LegacyTx) gas() uint64 { return tx.Gas }
|
||||||
func (tx *LegacyTx) gasPrice() *big.Int { return tx.GasPrice }
|
func (tx *LegacyTx) gasPrice() *big.Int { return tx.GasPrice }
|
||||||
func (tx *LegacyTx) tip() *big.Int { return tx.GasPrice }
|
func (tx *LegacyTx) gasTipCap() *big.Int { return tx.GasPrice }
|
||||||
func (tx *LegacyTx) feeCap() *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) 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() *common.Address { return tx.To }
|
func (tx *LegacyTx) to() *common.Address { return tx.To }
|
||||||
|
@ -36,7 +36,7 @@ var (
|
|||||||
ErrUnexpectedProtection = errors.New("transaction type does not supported EIP-155 protected signatures")
|
ErrUnexpectedProtection = errors.New("transaction type does not supported EIP-155 protected signatures")
|
||||||
ErrInvalidTxType = errors.New("transaction type not valid in this context")
|
ErrInvalidTxType = errors.New("transaction type not valid in this context")
|
||||||
ErrTxTypeNotSupported = errors.New("transaction type not supported")
|
ErrTxTypeNotSupported = errors.New("transaction type not supported")
|
||||||
ErrFeeCapTooLow = errors.New("fee cap less than base fee")
|
ErrGasFeeCapTooLow = errors.New("fee cap less than base fee")
|
||||||
errEmptyTypedTx = errors.New("empty typed transaction bytes")
|
errEmptyTypedTx = errors.New("empty typed transaction bytes")
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -77,8 +77,8 @@ type TxData interface {
|
|||||||
data() []byte
|
data() []byte
|
||||||
gas() uint64
|
gas() uint64
|
||||||
gasPrice() *big.Int
|
gasPrice() *big.Int
|
||||||
tip() *big.Int
|
gasTipCap() *big.Int
|
||||||
feeCap() *big.Int
|
gasFeeCap() *big.Int
|
||||||
value() *big.Int
|
value() *big.Int
|
||||||
nonce() uint64
|
nonce() uint64
|
||||||
to() *common.Address
|
to() *common.Address
|
||||||
@ -269,11 +269,11 @@ func (tx *Transaction) Gas() uint64 { return tx.inner.gas() }
|
|||||||
// GasPrice returns the gas price of the transaction.
|
// GasPrice returns the gas price of the transaction.
|
||||||
func (tx *Transaction) GasPrice() *big.Int { return new(big.Int).Set(tx.inner.gasPrice()) }
|
func (tx *Transaction) GasPrice() *big.Int { return new(big.Int).Set(tx.inner.gasPrice()) }
|
||||||
|
|
||||||
// Tip returns the tip per gas of the transaction.
|
// GasTipCap returns the gasTipCap per gas of the transaction.
|
||||||
func (tx *Transaction) Tip() *big.Int { return new(big.Int).Set(tx.inner.tip()) }
|
func (tx *Transaction) GasTipCap() *big.Int { return new(big.Int).Set(tx.inner.gasTipCap()) }
|
||||||
|
|
||||||
// FeeCap returns the fee cap per gas of the transaction.
|
// GasFeeCap returns the fee cap per gas of the transaction.
|
||||||
func (tx *Transaction) FeeCap() *big.Int { return new(big.Int).Set(tx.inner.feeCap()) }
|
func (tx *Transaction) GasFeeCap() *big.Int { return new(big.Int).Set(tx.inner.gasFeeCap()) }
|
||||||
|
|
||||||
// Value returns the ether amount of the transaction.
|
// Value returns the ether amount of the transaction.
|
||||||
func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.inner.value()) }
|
func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.inner.value()) }
|
||||||
@ -306,62 +306,62 @@ func (tx *Transaction) RawSignatureValues() (v, r, s *big.Int) {
|
|||||||
return tx.inner.rawSignatureValues()
|
return tx.inner.rawSignatureValues()
|
||||||
}
|
}
|
||||||
|
|
||||||
// FeeCapCmp compares the fee cap of two transactions.
|
// GasFeeCapCmp compares the fee cap of two transactions.
|
||||||
func (tx *Transaction) FeeCapCmp(other *Transaction) int {
|
func (tx *Transaction) GasFeeCapCmp(other *Transaction) int {
|
||||||
return tx.inner.feeCap().Cmp(other.inner.feeCap())
|
return tx.inner.gasFeeCap().Cmp(other.inner.gasFeeCap())
|
||||||
}
|
}
|
||||||
|
|
||||||
// FeeCapIntCmp compares the fee cap of the transaction against the given fee cap.
|
// GasFeeCapIntCmp compares the fee cap of the transaction against the given fee cap.
|
||||||
func (tx *Transaction) FeeCapIntCmp(other *big.Int) int {
|
func (tx *Transaction) GasFeeCapIntCmp(other *big.Int) int {
|
||||||
return tx.inner.feeCap().Cmp(other)
|
return tx.inner.gasFeeCap().Cmp(other)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TipCmp compares the tip of two transactions.
|
// GasTipCapCmp compares the gasTipCap of two transactions.
|
||||||
func (tx *Transaction) TipCmp(other *Transaction) int {
|
func (tx *Transaction) GasTipCapCmp(other *Transaction) int {
|
||||||
return tx.inner.tip().Cmp(other.inner.tip())
|
return tx.inner.gasTipCap().Cmp(other.inner.gasTipCap())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TipIntCmp compares the tip of the transaction against the given tip.
|
// GasTipCapIntCmp compares the gasTipCap of the transaction against the given gasTipCap.
|
||||||
func (tx *Transaction) TipIntCmp(other *big.Int) int {
|
func (tx *Transaction) GasTipCapIntCmp(other *big.Int) int {
|
||||||
return tx.inner.tip().Cmp(other)
|
return tx.inner.gasTipCap().Cmp(other)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EffectiveTip returns the effective miner tip for the given base fee.
|
// EffectiveGasTip returns the effective miner gasTipCap for the given base fee.
|
||||||
// Note: if the effective tip is negative, this method returns both error
|
// Note: if the effective gasTipCap is negative, this method returns both error
|
||||||
// the actual negative value, _and_ ErrFeeCapTooLow
|
// the actual negative value, _and_ ErrGasFeeCapTooLow
|
||||||
func (tx *Transaction) EffectiveTip(baseFee *big.Int) (*big.Int, error) {
|
func (tx *Transaction) EffectiveGasTip(baseFee *big.Int) (*big.Int, error) {
|
||||||
if baseFee == nil {
|
if baseFee == nil {
|
||||||
return tx.Tip(), nil
|
return tx.GasTipCap(), nil
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
feeCap := tx.FeeCap()
|
gasFeeCap := tx.GasFeeCap()
|
||||||
if feeCap.Cmp(baseFee) == -1 {
|
if gasFeeCap.Cmp(baseFee) == -1 {
|
||||||
err = ErrFeeCapTooLow
|
err = ErrGasFeeCapTooLow
|
||||||
}
|
}
|
||||||
return math.BigMin(tx.Tip(), feeCap.Sub(feeCap, baseFee)), err
|
return math.BigMin(tx.GasTipCap(), gasFeeCap.Sub(gasFeeCap, baseFee)), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// EffectiveTipValue is identical to EffectiveTip, but does not return an
|
// EffectiveGasTipValue is identical to EffectiveGasTip, but does not return an
|
||||||
// error in case the effective tip is negative
|
// error in case the effective gasTipCap is negative
|
||||||
func (tx *Transaction) EffectiveTipValue(baseFee *big.Int) *big.Int {
|
func (tx *Transaction) EffectiveGasTipValue(baseFee *big.Int) *big.Int {
|
||||||
effectiveTip, _ := tx.EffectiveTip(baseFee)
|
effectiveTip, _ := tx.EffectiveGasTip(baseFee)
|
||||||
return effectiveTip
|
return effectiveTip
|
||||||
}
|
}
|
||||||
|
|
||||||
// EffectiveTipCmp compares the effective tip of two transactions assuming the given base fee.
|
// EffectiveGasTipCmp compares the effective gasTipCap of two transactions assuming the given base fee.
|
||||||
func (tx *Transaction) EffectiveTipCmp(other *Transaction, baseFee *big.Int) int {
|
func (tx *Transaction) EffectiveGasTipCmp(other *Transaction, baseFee *big.Int) int {
|
||||||
if baseFee == nil {
|
if baseFee == nil {
|
||||||
return tx.TipCmp(other)
|
return tx.GasTipCapCmp(other)
|
||||||
}
|
}
|
||||||
return tx.EffectiveTipValue(baseFee).Cmp(other.EffectiveTipValue(baseFee))
|
return tx.EffectiveGasTipValue(baseFee).Cmp(other.EffectiveGasTipValue(baseFee))
|
||||||
}
|
}
|
||||||
|
|
||||||
// EffectiveTipIntCmp compares the effective tip of a transaction to the given tip.
|
// EffectiveTipIntCmp compares the effective gasTipCap of a transaction to the given gasTipCap.
|
||||||
func (tx *Transaction) EffectiveTipIntCmp(other *big.Int, baseFee *big.Int) int {
|
func (tx *Transaction) EffectiveTipIntCmp(other *big.Int, baseFee *big.Int) int {
|
||||||
if baseFee == nil {
|
if baseFee == nil {
|
||||||
return tx.TipIntCmp(other)
|
return tx.GasTipCapIntCmp(other)
|
||||||
}
|
}
|
||||||
return tx.EffectiveTipValue(baseFee).Cmp(other)
|
return tx.EffectiveGasTipValue(baseFee).Cmp(other)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hash returns the transaction hash.
|
// Hash returns the transaction hash.
|
||||||
@ -449,17 +449,17 @@ func (s TxByNonce) Len() int { return len(s) }
|
|||||||
func (s TxByNonce) Less(i, j int) bool { return s[i].Nonce() < s[j].Nonce() }
|
func (s TxByNonce) Less(i, j int) bool { return s[i].Nonce() < s[j].Nonce() }
|
||||||
func (s TxByNonce) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
func (s TxByNonce) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||||
|
|
||||||
// TxWithMinerFee wraps a transaction with its gas price or effective miner tip
|
// TxWithMinerFee wraps a transaction with its gas price or effective miner gasTipCap
|
||||||
type TxWithMinerFee struct {
|
type TxWithMinerFee struct {
|
||||||
tx *Transaction
|
tx *Transaction
|
||||||
minerFee *big.Int
|
minerFee *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTxWithMinerFee creates a wrapped transaction, calculating the effective
|
// NewTxWithMinerFee creates a wrapped transaction, calculating the effective
|
||||||
// miner tip if a base fee is provided.
|
// miner gasTipCap if a base fee is provided.
|
||||||
// Returns error in case of a negative effective miner tip.
|
// Returns error in case of a negative effective miner gasTipCap.
|
||||||
func NewTxWithMinerFee(tx *Transaction, baseFee *big.Int) (*TxWithMinerFee, error) {
|
func NewTxWithMinerFee(tx *Transaction, baseFee *big.Int) (*TxWithMinerFee, error) {
|
||||||
minerFee, err := tx.EffectiveTip(baseFee)
|
minerFee, err := tx.EffectiveGasTip(baseFee)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -575,14 +575,14 @@ type Message struct {
|
|||||||
amount *big.Int
|
amount *big.Int
|
||||||
gasLimit uint64
|
gasLimit uint64
|
||||||
gasPrice *big.Int
|
gasPrice *big.Int
|
||||||
feeCap *big.Int
|
gasFeeCap *big.Int
|
||||||
tip *big.Int
|
gasTipCap *big.Int
|
||||||
data []byte
|
data []byte
|
||||||
accessList AccessList
|
accessList AccessList
|
||||||
checkNonce bool
|
checkNonce bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice, feeCap, tip *big.Int, data []byte, accessList AccessList, checkNonce bool) Message {
|
func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice, gasFeeCap, gasTipCap *big.Int, data []byte, accessList AccessList, checkNonce bool) Message {
|
||||||
return Message{
|
return Message{
|
||||||
from: from,
|
from: from,
|
||||||
to: to,
|
to: to,
|
||||||
@ -590,8 +590,8 @@ func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *b
|
|||||||
amount: amount,
|
amount: amount,
|
||||||
gasLimit: gasLimit,
|
gasLimit: gasLimit,
|
||||||
gasPrice: gasPrice,
|
gasPrice: gasPrice,
|
||||||
feeCap: feeCap,
|
gasFeeCap: gasFeeCap,
|
||||||
tip: tip,
|
gasTipCap: gasTipCap,
|
||||||
data: data,
|
data: data,
|
||||||
accessList: accessList,
|
accessList: accessList,
|
||||||
checkNonce: checkNonce,
|
checkNonce: checkNonce,
|
||||||
@ -604,8 +604,8 @@ func (tx *Transaction) AsMessage(s Signer, baseFee *big.Int) (Message, error) {
|
|||||||
nonce: tx.Nonce(),
|
nonce: tx.Nonce(),
|
||||||
gasLimit: tx.Gas(),
|
gasLimit: tx.Gas(),
|
||||||
gasPrice: new(big.Int).Set(tx.GasPrice()),
|
gasPrice: new(big.Int).Set(tx.GasPrice()),
|
||||||
feeCap: new(big.Int).Set(tx.FeeCap()),
|
gasFeeCap: new(big.Int).Set(tx.GasFeeCap()),
|
||||||
tip: new(big.Int).Set(tx.Tip()),
|
gasTipCap: new(big.Int).Set(tx.GasTipCap()),
|
||||||
to: tx.To(),
|
to: tx.To(),
|
||||||
amount: tx.Value(),
|
amount: tx.Value(),
|
||||||
data: tx.Data(),
|
data: tx.Data(),
|
||||||
@ -614,7 +614,7 @@ func (tx *Transaction) AsMessage(s Signer, baseFee *big.Int) (Message, error) {
|
|||||||
}
|
}
|
||||||
// If baseFee provided, set gasPrice to effectiveGasPrice.
|
// If baseFee provided, set gasPrice to effectiveGasPrice.
|
||||||
if baseFee != nil {
|
if baseFee != nil {
|
||||||
msg.gasPrice = math.BigMin(msg.gasPrice.Add(msg.tip, baseFee), msg.feeCap)
|
msg.gasPrice = math.BigMin(msg.gasPrice.Add(msg.gasTipCap, baseFee), msg.gasFeeCap)
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
msg.from, err = Sender(s, tx)
|
msg.from, err = Sender(s, tx)
|
||||||
@ -624,8 +624,8 @@ func (tx *Transaction) AsMessage(s Signer, baseFee *big.Int) (Message, error) {
|
|||||||
func (m Message) From() common.Address { return m.from }
|
func (m Message) From() common.Address { return m.from }
|
||||||
func (m Message) To() *common.Address { return m.to }
|
func (m Message) To() *common.Address { return m.to }
|
||||||
func (m Message) GasPrice() *big.Int { return m.gasPrice }
|
func (m Message) GasPrice() *big.Int { return m.gasPrice }
|
||||||
func (m Message) FeeCap() *big.Int { return m.feeCap }
|
func (m Message) GasFeeCap() *big.Int { return m.gasFeeCap }
|
||||||
func (m Message) Tip() *big.Int { return m.tip }
|
func (m Message) GasTipCap() *big.Int { return m.gasTipCap }
|
||||||
func (m Message) Value() *big.Int { return m.amount }
|
func (m Message) Value() *big.Int { return m.amount }
|
||||||
func (m Message) Gas() uint64 { return m.gasLimit }
|
func (m Message) Gas() uint64 { return m.gasLimit }
|
||||||
func (m Message) Nonce() uint64 { return m.nonce }
|
func (m Message) Nonce() uint64 { return m.nonce }
|
||||||
|
@ -86,8 +86,8 @@ func (t *Transaction) MarshalJSON() ([]byte, error) {
|
|||||||
enc.AccessList = &tx.AccessList
|
enc.AccessList = &tx.AccessList
|
||||||
enc.Nonce = (*hexutil.Uint64)(&tx.Nonce)
|
enc.Nonce = (*hexutil.Uint64)(&tx.Nonce)
|
||||||
enc.Gas = (*hexutil.Uint64)(&tx.Gas)
|
enc.Gas = (*hexutil.Uint64)(&tx.Gas)
|
||||||
enc.MaxFeePerGas = (*hexutil.Big)(tx.FeeCap)
|
enc.MaxFeePerGas = (*hexutil.Big)(tx.GasFeeCap)
|
||||||
enc.MaxPriorityFeePerGas = (*hexutil.Big)(tx.Tip)
|
enc.MaxPriorityFeePerGas = (*hexutil.Big)(tx.GasTipCap)
|
||||||
enc.Value = (*hexutil.Big)(tx.Value)
|
enc.Value = (*hexutil.Big)(tx.Value)
|
||||||
enc.Data = (*hexutil.Bytes)(&tx.Data)
|
enc.Data = (*hexutil.Bytes)(&tx.Data)
|
||||||
enc.To = t.To()
|
enc.To = t.To()
|
||||||
@ -227,11 +227,11 @@ func (t *Transaction) UnmarshalJSON(input []byte) error {
|
|||||||
if dec.MaxPriorityFeePerGas == nil {
|
if dec.MaxPriorityFeePerGas == nil {
|
||||||
return errors.New("missing required field 'maxPriorityFeePerGas' for txdata")
|
return errors.New("missing required field 'maxPriorityFeePerGas' for txdata")
|
||||||
}
|
}
|
||||||
itx.Tip = (*big.Int)(dec.MaxPriorityFeePerGas)
|
itx.GasTipCap = (*big.Int)(dec.MaxPriorityFeePerGas)
|
||||||
if dec.MaxFeePerGas == nil {
|
if dec.MaxFeePerGas == nil {
|
||||||
return errors.New("missing required field 'maxFeePerGas' for txdata")
|
return errors.New("missing required field 'maxFeePerGas' for txdata")
|
||||||
}
|
}
|
||||||
itx.FeeCap = (*big.Int)(dec.MaxFeePerGas)
|
itx.GasFeeCap = (*big.Int)(dec.MaxFeePerGas)
|
||||||
if dec.Gas == nil {
|
if dec.Gas == nil {
|
||||||
return errors.New("missing required field 'gas' for txdata")
|
return errors.New("missing required field 'gas' for txdata")
|
||||||
}
|
}
|
||||||
|
@ -226,8 +226,8 @@ func (s londonSigner) Hash(tx *Transaction) common.Hash {
|
|||||||
[]interface{}{
|
[]interface{}{
|
||||||
s.chainId,
|
s.chainId,
|
||||||
tx.Nonce(),
|
tx.Nonce(),
|
||||||
tx.Tip(),
|
tx.GasTipCap(),
|
||||||
tx.FeeCap(),
|
tx.GasFeeCap(),
|
||||||
tx.Gas(),
|
tx.Gas(),
|
||||||
tx.To(),
|
tx.To(),
|
||||||
tx.Value(),
|
tx.Value(),
|
||||||
|
@ -288,27 +288,27 @@ func testTransactionPriceNonceSort(t *testing.T, baseFee *big.Int) {
|
|||||||
count := 25
|
count := 25
|
||||||
for i := 0; i < 25; i++ {
|
for i := 0; i < 25; i++ {
|
||||||
var tx *Transaction
|
var tx *Transaction
|
||||||
feeCap := rand.Intn(50)
|
gasFeeCap := rand.Intn(50)
|
||||||
if baseFee == nil {
|
if baseFee == nil {
|
||||||
tx = NewTx(&LegacyTx{
|
tx = NewTx(&LegacyTx{
|
||||||
Nonce: uint64(start + i),
|
Nonce: uint64(start + i),
|
||||||
To: &common.Address{},
|
To: &common.Address{},
|
||||||
Value: big.NewInt(100),
|
Value: big.NewInt(100),
|
||||||
Gas: 100,
|
Gas: 100,
|
||||||
GasPrice: big.NewInt(int64(feeCap)),
|
GasPrice: big.NewInt(int64(gasFeeCap)),
|
||||||
Data: nil,
|
Data: nil,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
tx = NewTx(&DynamicFeeTx{
|
tx = NewTx(&DynamicFeeTx{
|
||||||
Nonce: uint64(start + i),
|
Nonce: uint64(start + i),
|
||||||
To: &common.Address{},
|
To: &common.Address{},
|
||||||
Value: big.NewInt(100),
|
Value: big.NewInt(100),
|
||||||
Gas: 100,
|
Gas: 100,
|
||||||
FeeCap: big.NewInt(int64(feeCap)),
|
GasFeeCap: big.NewInt(int64(gasFeeCap)),
|
||||||
Tip: big.NewInt(int64(rand.Intn(feeCap + 1))),
|
GasTipCap: big.NewInt(int64(rand.Intn(gasFeeCap + 1))),
|
||||||
Data: nil,
|
Data: nil,
|
||||||
})
|
})
|
||||||
if count == 25 && int64(feeCap) < baseFee.Int64() {
|
if count == 25 && int64(gasFeeCap) < baseFee.Int64() {
|
||||||
count = i
|
count = i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -345,8 +345,8 @@ func testTransactionPriceNonceSort(t *testing.T, baseFee *big.Int) {
|
|||||||
if i+1 < len(txs) {
|
if i+1 < len(txs) {
|
||||||
next := txs[i+1]
|
next := txs[i+1]
|
||||||
fromNext, _ := Sender(signer, next)
|
fromNext, _ := Sender(signer, next)
|
||||||
tip, err := txi.EffectiveTip(baseFee)
|
tip, err := txi.EffectiveGasTip(baseFee)
|
||||||
nextTip, nextErr := next.EffectiveTip(baseFee)
|
nextTip, nextErr := next.EffectiveGasTip(baseFee)
|
||||||
if err != nil || nextErr != nil {
|
if err != nil || nextErr != nil {
|
||||||
t.Errorf("error calculating effective tip")
|
t.Errorf("error calculating effective tip")
|
||||||
}
|
}
|
||||||
|
@ -210,8 +210,8 @@ func (s *txSorter) Swap(i, j int) {
|
|||||||
func (s *txSorter) Less(i, j int) bool {
|
func (s *txSorter) Less(i, j int) bool {
|
||||||
// It's okay to discard the error because a tx would never be
|
// It's okay to discard the error because a tx would never be
|
||||||
// accepted into a block with an invalid effective tip.
|
// accepted into a block with an invalid effective tip.
|
||||||
tip1, _ := s.txs[i].EffectiveTip(s.baseFee)
|
tip1, _ := s.txs[i].EffectiveGasTip(s.baseFee)
|
||||||
tip2, _ := s.txs[j].EffectiveTip(s.baseFee)
|
tip2, _ := s.txs[j].EffectiveGasTip(s.baseFee)
|
||||||
return tip1.Cmp(tip2) < 0
|
return tip1.Cmp(tip2) < 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,7 +236,7 @@ func (gpo *Oracle) getBlockValues(ctx context.Context, signer types.Signer, bloc
|
|||||||
|
|
||||||
var prices []*big.Int
|
var prices []*big.Int
|
||||||
for _, tx := range sorter.txs {
|
for _, tx := range sorter.txs {
|
||||||
tip, _ := tx.EffectiveTip(block.BaseFee())
|
tip, _ := tx.EffectiveGasTip(block.BaseFee())
|
||||||
if ignoreUnder != nil && tip.Cmp(ignoreUnder) == -1 {
|
if ignoreUnder != nil && tip.Cmp(ignoreUnder) == -1 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -80,13 +80,13 @@ func newTestBackend(t *testing.T, londonBlock *big.Int) *testBackend {
|
|||||||
var tx *types.Transaction
|
var tx *types.Transaction
|
||||||
if londonBlock != nil && b.Number().Cmp(londonBlock) >= 0 {
|
if londonBlock != nil && b.Number().Cmp(londonBlock) >= 0 {
|
||||||
txdata := &types.DynamicFeeTx{
|
txdata := &types.DynamicFeeTx{
|
||||||
ChainID: gspec.Config.ChainID,
|
ChainID: gspec.Config.ChainID,
|
||||||
Nonce: b.TxNonce(addr),
|
Nonce: b.TxNonce(addr),
|
||||||
To: &common.Address{},
|
To: &common.Address{},
|
||||||
Gas: 30000,
|
Gas: 30000,
|
||||||
FeeCap: big.NewInt(100 * params.GWei),
|
GasFeeCap: big.NewInt(100 * params.GWei),
|
||||||
Tip: big.NewInt(int64(i+1) * params.GWei),
|
GasTipCap: big.NewInt(int64(i+1) * params.GWei),
|
||||||
Data: []byte{},
|
Data: []byte{},
|
||||||
}
|
}
|
||||||
tx = types.NewTx(txdata)
|
tx = types.NewTx(txdata)
|
||||||
} else {
|
} else {
|
||||||
|
@ -21,12 +21,14 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/big"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum"
|
"github.com/ethereum/go-ethereum"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
"github.com/ethereum/go-ethereum/common/math"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
@ -218,7 +220,50 @@ func (t *Transaction) GasPrice(ctx context.Context) (hexutil.Big, error) {
|
|||||||
if err != nil || tx == nil {
|
if err != nil || tx == nil {
|
||||||
return hexutil.Big{}, err
|
return hexutil.Big{}, err
|
||||||
}
|
}
|
||||||
return hexutil.Big(*tx.GasPrice()), nil
|
switch tx.Type() {
|
||||||
|
case types.AccessListTxType:
|
||||||
|
return hexutil.Big(*tx.GasPrice()), nil
|
||||||
|
case types.DynamicFeeTxType:
|
||||||
|
if t.block != nil {
|
||||||
|
if baseFee, _ := t.block.BaseFeePerGas(ctx); baseFee != nil {
|
||||||
|
// price = min(tip, gasFeeCap - baseFee) + baseFee
|
||||||
|
return (hexutil.Big)(*math.BigMin(new(big.Int).Add(tx.GasTipCap(), baseFee.ToInt()), tx.GasFeeCap())), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hexutil.Big(*tx.GasPrice()), nil
|
||||||
|
default:
|
||||||
|
return hexutil.Big(*tx.GasPrice()), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Transaction) MaxFeePerGas(ctx context.Context) (*hexutil.Big, error) {
|
||||||
|
tx, err := t.resolve(ctx)
|
||||||
|
if err != nil || tx == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
switch tx.Type() {
|
||||||
|
case types.AccessListTxType:
|
||||||
|
return nil, nil
|
||||||
|
case types.DynamicFeeTxType:
|
||||||
|
return (*hexutil.Big)(tx.GasFeeCap()), nil
|
||||||
|
default:
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Transaction) MaxPriorityFeePerGas(ctx context.Context) (*hexutil.Big, error) {
|
||||||
|
tx, err := t.resolve(ctx)
|
||||||
|
if err != nil || tx == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
switch tx.Type() {
|
||||||
|
case types.AccessListTxType:
|
||||||
|
return nil, nil
|
||||||
|
case types.DynamicFeeTxType:
|
||||||
|
return (*hexutil.Big)(tx.GasTipCap()), nil
|
||||||
|
default:
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transaction) Value(ctx context.Context) (hexutil.Big, error) {
|
func (t *Transaction) Value(ctx context.Context) (hexutil.Big, error) {
|
||||||
@ -517,6 +562,17 @@ func (b *Block) GasUsed(ctx context.Context) (Long, error) {
|
|||||||
return Long(header.GasUsed), nil
|
return Long(header.GasUsed), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *Block) BaseFeePerGas(ctx context.Context) (*hexutil.Big, error) {
|
||||||
|
header, err := b.resolveHeader(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if header.BaseFee == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return (*hexutil.Big)(header.BaseFee), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (b *Block) Parent(ctx context.Context) (*Block, error) {
|
func (b *Block) Parent(ctx context.Context) (*Block, error) {
|
||||||
// If the block header hasn't been fetched, and we'll need it, fetch it.
|
// If the block header hasn't been fetched, and we'll need it, fetch it.
|
||||||
if b.numberOrHash == nil && b.header == nil {
|
if b.numberOrHash == nil && b.header == nil {
|
||||||
@ -833,12 +889,14 @@ func (b *Block) Account(ctx context.Context, args struct {
|
|||||||
// CallData encapsulates arguments to `call` or `estimateGas`.
|
// CallData encapsulates arguments to `call` or `estimateGas`.
|
||||||
// All arguments are optional.
|
// All arguments are optional.
|
||||||
type CallData struct {
|
type CallData struct {
|
||||||
From *common.Address // The Ethereum address the call is from.
|
From *common.Address // The Ethereum address the call is from.
|
||||||
To *common.Address // The Ethereum address the call is to.
|
To *common.Address // The Ethereum address the call is to.
|
||||||
Gas *hexutil.Uint64 // The amount of gas provided for the call.
|
Gas *hexutil.Uint64 // The amount of gas provided for the call.
|
||||||
GasPrice *hexutil.Big // The price of each unit of gas, in wei.
|
GasPrice *hexutil.Big // The price of each unit of gas, in wei.
|
||||||
Value *hexutil.Big // The value sent along with the call.
|
MaxFeePerGas *hexutil.Big // The max price of each unit of gas, in wei (1559).
|
||||||
Data *hexutil.Bytes // Any data sent with the call.
|
MaxPriorityFeePerGas *hexutil.Big // The max tip of each unit of gas, in wei (1559).
|
||||||
|
Value *hexutil.Big // The value sent along with the call.
|
||||||
|
Data *hexutil.Bytes // Any data sent with the call.
|
||||||
}
|
}
|
||||||
|
|
||||||
// CallResult encapsulates the result of an invocation of the `call` accessor.
|
// CallResult encapsulates the result of an invocation of the `call` accessor.
|
||||||
|
@ -94,6 +94,10 @@ const schema string = `
|
|||||||
value: BigInt!
|
value: BigInt!
|
||||||
# GasPrice is the price offered to miners for gas, in wei per unit.
|
# GasPrice is the price offered to miners for gas, in wei per unit.
|
||||||
gasPrice: BigInt!
|
gasPrice: BigInt!
|
||||||
|
# MaxFeePerGas is the maximum fee per gas offered to include a transaction, in wei.
|
||||||
|
maxFeePerGas: BigInt
|
||||||
|
# MaxPriorityFeePerGas is the maximum miner tip per gas offered to include a transaction, in wei.
|
||||||
|
maxPriorityFeePerGas: BigInt
|
||||||
# Gas is the maximum amount of gas this transaction can consume.
|
# Gas is the maximum amount of gas this transaction can consume.
|
||||||
gas: Long!
|
gas: Long!
|
||||||
# InputData is the data supplied to the target of the transaction.
|
# InputData is the data supplied to the target of the transaction.
|
||||||
@ -176,6 +180,8 @@ const schema string = `
|
|||||||
gasLimit: Long!
|
gasLimit: Long!
|
||||||
# GasUsed is the amount of gas that was used executing transactions in this block.
|
# GasUsed is the amount of gas that was used executing transactions in this block.
|
||||||
gasUsed: Long!
|
gasUsed: Long!
|
||||||
|
# BaseFeePerGas is the fee perunit of gas burned by the protocol in this block.
|
||||||
|
baseFeePerGas: BigInt
|
||||||
# Timestamp is the unix timestamp at which this block was mined.
|
# Timestamp is the unix timestamp at which this block was mined.
|
||||||
timestamp: Long!
|
timestamp: Long!
|
||||||
# LogsBloom is a bloom filter that can be used to check if a block may
|
# LogsBloom is a bloom filter that can be used to check if a block may
|
||||||
@ -231,6 +237,10 @@ const schema string = `
|
|||||||
gas: Long
|
gas: Long
|
||||||
# GasPrice is the price, in wei, offered for each unit of gas.
|
# GasPrice is the price, in wei, offered for each unit of gas.
|
||||||
gasPrice: BigInt
|
gasPrice: BigInt
|
||||||
|
# MaxFeePerGas is the maximum fee per gas offered, in wei.
|
||||||
|
maxFeePerGas: BigInt
|
||||||
|
# MaxPriorityFeePerGas is the maximum miner tip per gas offered, in wei.
|
||||||
|
maxPriorityFeePerGas: BigInt
|
||||||
# Value is the value, in wei, sent along with the call.
|
# Value is the value, in wei, sent along with the call.
|
||||||
value: BigInt
|
value: BigInt
|
||||||
# Data is the data sent to the callee.
|
# Data is the data sent to the callee.
|
||||||
|
@ -113,15 +113,14 @@ type ChainSyncReader interface {
|
|||||||
|
|
||||||
// CallMsg contains parameters for contract calls.
|
// CallMsg contains parameters for contract calls.
|
||||||
type CallMsg struct {
|
type CallMsg struct {
|
||||||
From common.Address // the sender of the 'transaction'
|
From common.Address // the sender of the 'transaction'
|
||||||
To *common.Address // the destination contract (nil for contract creation)
|
To *common.Address // the destination contract (nil for contract creation)
|
||||||
Gas uint64 // if 0, the call executes with near-infinite gas
|
Gas uint64 // if 0, the call executes with near-infinite gas
|
||||||
GasPrice *big.Int // wei <-> gas exchange ratio
|
GasPrice *big.Int // wei <-> gas exchange ratio
|
||||||
Value *big.Int // amount of wei sent along with the call
|
GasFeeCap *big.Int // EIP-1559 fee cap per gas.
|
||||||
Data []byte // input data, usually an ABI-encoded contract method invocation
|
GasTipCap *big.Int // EIP-1559 tip per gas.
|
||||||
|
Value *big.Int // amount of wei sent along with the call
|
||||||
FeeCap *big.Int // EIP-1559 fee cap per gas.
|
Data []byte // input data, usually an ABI-encoded contract method invocation
|
||||||
Tip *big.Int // EIP-1559 tip per gas.
|
|
||||||
|
|
||||||
AccessList types.AccessList // EIP-2930 access list.
|
AccessList types.AccessList // EIP-2930 access list.
|
||||||
}
|
}
|
||||||
|
@ -1198,8 +1198,8 @@ type RPCTransaction struct {
|
|||||||
From common.Address `json:"from"`
|
From common.Address `json:"from"`
|
||||||
Gas hexutil.Uint64 `json:"gas"`
|
Gas hexutil.Uint64 `json:"gas"`
|
||||||
GasPrice *hexutil.Big `json:"gasPrice"`
|
GasPrice *hexutil.Big `json:"gasPrice"`
|
||||||
FeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"`
|
GasFeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"`
|
||||||
Tip *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"`
|
GasTipCap *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"`
|
||||||
Hash common.Hash `json:"hash"`
|
Hash common.Hash `json:"hash"`
|
||||||
Input hexutil.Bytes `json:"input"`
|
Input hexutil.Bytes `json:"input"`
|
||||||
Nonce hexutil.Uint64 `json:"nonce"`
|
Nonce hexutil.Uint64 `json:"nonce"`
|
||||||
@ -1257,12 +1257,12 @@ func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber
|
|||||||
al := tx.AccessList()
|
al := tx.AccessList()
|
||||||
result.Accesses = &al
|
result.Accesses = &al
|
||||||
result.ChainID = (*hexutil.Big)(tx.ChainId())
|
result.ChainID = (*hexutil.Big)(tx.ChainId())
|
||||||
result.FeeCap = (*hexutil.Big)(tx.FeeCap())
|
result.GasFeeCap = (*hexutil.Big)(tx.GasFeeCap())
|
||||||
result.Tip = (*hexutil.Big)(tx.Tip())
|
result.GasTipCap = (*hexutil.Big)(tx.GasTipCap())
|
||||||
// if the transaction has been mined, compute the effective gas price
|
// if the transaction has been mined, compute the effective gas price
|
||||||
if baseFee != nil && blockHash != (common.Hash{}) {
|
if baseFee != nil && blockHash != (common.Hash{}) {
|
||||||
// price = min(tip, feeCap - baseFee) + baseFee
|
// price = min(tip, gasFeeCap - baseFee) + baseFee
|
||||||
price := math.BigMin(new(big.Int).Add(tx.Tip(), baseFee), tx.FeeCap())
|
price := math.BigMin(new(big.Int).Add(tx.GasTipCap(), baseFee), tx.GasFeeCap())
|
||||||
result.GasPrice = (*hexutil.Big)(price)
|
result.GasPrice = (*hexutil.Big)(price)
|
||||||
} else {
|
} else {
|
||||||
result.GasPrice = nil
|
result.GasPrice = nil
|
||||||
|
@ -34,14 +34,14 @@ import (
|
|||||||
// TransactionArgs represents the arguments to construct a new transaction
|
// TransactionArgs represents the arguments to construct a new transaction
|
||||||
// or a message call.
|
// or a message call.
|
||||||
type TransactionArgs struct {
|
type TransactionArgs struct {
|
||||||
From *common.Address `json:"from"`
|
From *common.Address `json:"from"`
|
||||||
To *common.Address `json:"to"`
|
To *common.Address `json:"to"`
|
||||||
Gas *hexutil.Uint64 `json:"gas"`
|
Gas *hexutil.Uint64 `json:"gas"`
|
||||||
GasPrice *hexutil.Big `json:"gasPrice"`
|
GasPrice *hexutil.Big `json:"gasPrice"`
|
||||||
FeeCap *hexutil.Big `json:"maxFeePerGas"`
|
MaxFeePerGas *hexutil.Big `json:"maxFeePerGas"`
|
||||||
Tip *hexutil.Big `json:"maxPriorityFeePerGas"`
|
MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas"`
|
||||||
Value *hexutil.Big `json:"value"`
|
Value *hexutil.Big `json:"value"`
|
||||||
Nonce *hexutil.Uint64 `json:"nonce"`
|
Nonce *hexutil.Uint64 `json:"nonce"`
|
||||||
|
|
||||||
// We accept "data" and "input" for backwards-compatibility reasons.
|
// We accept "data" and "input" for backwards-compatibility reasons.
|
||||||
// "input" is the newer name and should be preferred by clients.
|
// "input" is the newer name and should be preferred by clients.
|
||||||
@ -75,31 +75,31 @@ func (arg *TransactionArgs) data() []byte {
|
|||||||
|
|
||||||
// setDefaults fills in default values for unspecified tx fields.
|
// setDefaults fills in default values for unspecified tx fields.
|
||||||
func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend) error {
|
func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend) error {
|
||||||
if args.GasPrice != nil && (args.FeeCap != nil || args.Tip != nil) {
|
if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) {
|
||||||
return errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
|
return errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
|
||||||
}
|
}
|
||||||
// After london, default to 1559 unless gasPrice is set
|
// After london, default to 1559 unless gasPrice is set
|
||||||
head := b.CurrentHeader()
|
head := b.CurrentHeader()
|
||||||
if b.ChainConfig().IsLondon(head.Number) && args.GasPrice == nil {
|
if b.ChainConfig().IsLondon(head.Number) && args.GasPrice == nil {
|
||||||
if args.Tip == nil {
|
if args.MaxPriorityFeePerGas == nil {
|
||||||
tip, err := b.SuggestGasTipCap(ctx)
|
tip, err := b.SuggestGasTipCap(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
args.Tip = (*hexutil.Big)(tip)
|
args.MaxPriorityFeePerGas = (*hexutil.Big)(tip)
|
||||||
}
|
}
|
||||||
if args.FeeCap == nil {
|
if args.MaxFeePerGas == nil {
|
||||||
feeCap := new(big.Int).Add(
|
gasFeeCap := new(big.Int).Add(
|
||||||
(*big.Int)(args.Tip),
|
(*big.Int)(args.MaxPriorityFeePerGas),
|
||||||
new(big.Int).Mul(head.BaseFee, big.NewInt(2)),
|
new(big.Int).Mul(head.BaseFee, big.NewInt(2)),
|
||||||
)
|
)
|
||||||
args.FeeCap = (*hexutil.Big)(feeCap)
|
args.MaxFeePerGas = (*hexutil.Big)(gasFeeCap)
|
||||||
}
|
}
|
||||||
if args.FeeCap.ToInt().Cmp(args.Tip.ToInt()) < 0 {
|
if args.MaxFeePerGas.ToInt().Cmp(args.MaxPriorityFeePerGas.ToInt()) < 0 {
|
||||||
return fmt.Errorf("maxFeePerGas (%v) < maxPriorityFeePerGas (%v)", args.FeeCap, args.Tip)
|
return fmt.Errorf("maxFeePerGas (%v) < maxPriorityFeePerGas (%v)", args.MaxFeePerGas, args.MaxPriorityFeePerGas)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if args.FeeCap != nil || args.Tip != nil {
|
if args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil {
|
||||||
return errors.New("maxFeePerGas or maxPriorityFeePerGas specified but london is not active yet")
|
return errors.New("maxFeePerGas or maxPriorityFeePerGas specified but london is not active yet")
|
||||||
}
|
}
|
||||||
if args.GasPrice == nil {
|
if args.GasPrice == nil {
|
||||||
@ -134,14 +134,14 @@ func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend) error {
|
|||||||
// These fields are immutable during the estimation, safe to
|
// These fields are immutable during the estimation, safe to
|
||||||
// pass the pointer directly.
|
// pass the pointer directly.
|
||||||
callArgs := TransactionArgs{
|
callArgs := TransactionArgs{
|
||||||
From: args.From,
|
From: args.From,
|
||||||
To: args.To,
|
To: args.To,
|
||||||
GasPrice: args.GasPrice,
|
GasPrice: args.GasPrice,
|
||||||
FeeCap: args.FeeCap,
|
MaxFeePerGas: args.MaxFeePerGas,
|
||||||
Tip: args.Tip,
|
MaxPriorityFeePerGas: args.MaxPriorityFeePerGas,
|
||||||
Value: args.Value,
|
Value: args.Value,
|
||||||
Data: args.Data,
|
Data: args.Data,
|
||||||
AccessList: args.AccessList,
|
AccessList: args.AccessList,
|
||||||
}
|
}
|
||||||
pendingBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber)
|
pendingBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber)
|
||||||
estimated, err := DoEstimateGas(ctx, b, callArgs, pendingBlockNr, b.RPCGasCap())
|
estimated, err := DoEstimateGas(ctx, b, callArgs, pendingBlockNr, b.RPCGasCap())
|
||||||
@ -161,7 +161,7 @@ func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend) error {
|
|||||||
// ToMessage converts TransactionArgs to the Message type used by the core evm
|
// ToMessage converts TransactionArgs to the Message type used by the core evm
|
||||||
func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (types.Message, error) {
|
func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (types.Message, error) {
|
||||||
// Reject invalid combinations of pre- and post-1559 fee styles
|
// Reject invalid combinations of pre- and post-1559 fee styles
|
||||||
if args.GasPrice != nil && (args.FeeCap != nil || args.Tip != nil) {
|
if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) {
|
||||||
return types.Message{}, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
|
return types.Message{}, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
|
||||||
}
|
}
|
||||||
// Set sender address or use zero address if none specified.
|
// Set sender address or use zero address if none specified.
|
||||||
@ -180,9 +180,9 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (t
|
|||||||
gas = globalGasCap
|
gas = globalGasCap
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
gasPrice *big.Int
|
gasPrice *big.Int
|
||||||
feeCap *big.Int
|
gasFeeCap *big.Int
|
||||||
tip *big.Int
|
gasTipCap *big.Int
|
||||||
)
|
)
|
||||||
if baseFee == nil {
|
if baseFee == nil {
|
||||||
// If there's no basefee, then it must be a non-1559 execution
|
// If there's no basefee, then it must be a non-1559 execution
|
||||||
@ -190,22 +190,22 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (t
|
|||||||
if args.GasPrice != nil {
|
if args.GasPrice != nil {
|
||||||
gasPrice = args.GasPrice.ToInt()
|
gasPrice = args.GasPrice.ToInt()
|
||||||
}
|
}
|
||||||
feeCap, tip = gasPrice, gasPrice
|
gasFeeCap, gasTipCap = gasPrice, gasPrice
|
||||||
} else {
|
} else {
|
||||||
// A basefee is provided, necessitating 1559-type execution
|
// A basefee is provided, necessitating 1559-type execution
|
||||||
if args.GasPrice != nil {
|
if args.GasPrice != nil {
|
||||||
gasPrice = args.GasPrice.ToInt()
|
gasPrice = args.GasPrice.ToInt()
|
||||||
feeCap, tip = gasPrice, gasPrice
|
gasFeeCap, gasTipCap = gasPrice, gasPrice
|
||||||
} else {
|
} else {
|
||||||
feeCap = new(big.Int)
|
gasFeeCap = new(big.Int)
|
||||||
if args.FeeCap != nil {
|
if args.MaxFeePerGas != nil {
|
||||||
feeCap = args.FeeCap.ToInt()
|
gasFeeCap = args.MaxFeePerGas.ToInt()
|
||||||
}
|
}
|
||||||
tip = new(big.Int)
|
gasTipCap = new(big.Int)
|
||||||
if args.Tip != nil {
|
if args.MaxPriorityFeePerGas != nil {
|
||||||
tip = args.Tip.ToInt()
|
gasTipCap = args.MaxPriorityFeePerGas.ToInt()
|
||||||
}
|
}
|
||||||
gasPrice = math.BigMin(new(big.Int).Add(tip, baseFee), feeCap)
|
gasPrice = math.BigMin(new(big.Int).Add(gasTipCap, baseFee), gasFeeCap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
value := new(big.Int)
|
value := new(big.Int)
|
||||||
@ -217,7 +217,7 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (t
|
|||||||
if args.AccessList != nil {
|
if args.AccessList != nil {
|
||||||
accessList = *args.AccessList
|
accessList = *args.AccessList
|
||||||
}
|
}
|
||||||
msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, feeCap, tip, data, accessList, false)
|
msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, gasFeeCap, gasTipCap, data, accessList, false)
|
||||||
return msg, nil
|
return msg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +226,7 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (t
|
|||||||
func (args *TransactionArgs) toTransaction() *types.Transaction {
|
func (args *TransactionArgs) toTransaction() *types.Transaction {
|
||||||
var data types.TxData
|
var data types.TxData
|
||||||
switch {
|
switch {
|
||||||
case args.FeeCap != nil:
|
case args.MaxFeePerGas != nil:
|
||||||
al := types.AccessList{}
|
al := types.AccessList{}
|
||||||
if args.AccessList != nil {
|
if args.AccessList != nil {
|
||||||
al = *args.AccessList
|
al = *args.AccessList
|
||||||
@ -236,8 +236,8 @@ func (args *TransactionArgs) toTransaction() *types.Transaction {
|
|||||||
ChainID: (*big.Int)(args.ChainID),
|
ChainID: (*big.Int)(args.ChainID),
|
||||||
Nonce: uint64(*args.Nonce),
|
Nonce: uint64(*args.Nonce),
|
||||||
Gas: uint64(*args.Gas),
|
Gas: uint64(*args.Gas),
|
||||||
FeeCap: (*big.Int)(args.FeeCap),
|
GasFeeCap: (*big.Int)(args.MaxFeePerGas),
|
||||||
Tip: (*big.Int)(args.Tip),
|
GasTipCap: (*big.Int)(args.MaxPriorityFeePerGas),
|
||||||
Value: (*big.Int)(args.Value),
|
Value: (*big.Int)(args.Value),
|
||||||
Data: args.data(),
|
Data: args.data(),
|
||||||
AccessList: al,
|
AccessList: al,
|
||||||
|
@ -155,7 +155,7 @@ func makeTransaction(nonce uint64, privKey *ecdsa.PrivateKey, signer types.Signe
|
|||||||
// larger buffer for creating both valid and invalid transactions.
|
// larger buffer for creating both valid and invalid transactions.
|
||||||
var buf = make([]byte, 32+5)
|
var buf = make([]byte, 32+5)
|
||||||
rand.Read(buf)
|
rand.Read(buf)
|
||||||
tip := new(big.Int).SetBytes(buf)
|
gasTipCap := new(big.Int).SetBytes(buf)
|
||||||
|
|
||||||
// If the given base fee is nil(the 1559 is still not available),
|
// If the given base fee is nil(the 1559 is still not available),
|
||||||
// generate a fake base fee in order to create 1559 tx forcibly.
|
// generate a fake base fee in order to create 1559 tx forcibly.
|
||||||
@ -163,18 +163,18 @@ func makeTransaction(nonce uint64, privKey *ecdsa.PrivateKey, signer types.Signe
|
|||||||
baseFee = new(big.Int).SetInt64(int64(rand.Int31()))
|
baseFee = new(big.Int).SetInt64(int64(rand.Int31()))
|
||||||
}
|
}
|
||||||
// Generate the feecap, 75% valid feecap and 25% unguaranted.
|
// Generate the feecap, 75% valid feecap and 25% unguaranted.
|
||||||
var feeCap *big.Int
|
var gasFeeCap *big.Int
|
||||||
if rand.Intn(4) == 0 {
|
if rand.Intn(4) == 0 {
|
||||||
rand.Read(buf)
|
rand.Read(buf)
|
||||||
feeCap = new(big.Int).SetBytes(buf)
|
gasFeeCap = new(big.Int).SetBytes(buf)
|
||||||
} else {
|
} else {
|
||||||
feeCap = new(big.Int).Add(baseFee, tip)
|
gasFeeCap = new(big.Int).Add(baseFee, gasTipCap)
|
||||||
}
|
}
|
||||||
return types.MustSignNewTx(privKey, signer, &types.DynamicFeeTx{
|
return types.MustSignNewTx(privKey, signer, &types.DynamicFeeTx{
|
||||||
ChainID: signer.ChainID(),
|
ChainID: signer.ChainID(),
|
||||||
Nonce: nonce,
|
Nonce: nonce,
|
||||||
Tip: tip,
|
GasTipCap: gasTipCap,
|
||||||
FeeCap: feeCap,
|
GasFeeCap: gasFeeCap,
|
||||||
Gas: 21000,
|
Gas: 21000,
|
||||||
To: &recipient,
|
To: &recipient,
|
||||||
Value: big.NewInt(100),
|
Value: big.NewInt(100),
|
||||||
|
@ -1052,7 +1052,7 @@ func (w *worker) postSideBlock(event core.ChainSideEvent) {
|
|||||||
func totalFees(block *types.Block, receipts []*types.Receipt) *big.Float {
|
func totalFees(block *types.Block, receipts []*types.Receipt) *big.Float {
|
||||||
feesWei := new(big.Int)
|
feesWei := new(big.Int)
|
||||||
for i, tx := range block.Transactions() {
|
for i, tx := range block.Transactions() {
|
||||||
minerFee, _ := tx.EffectiveTip(block.BaseFee())
|
minerFee, _ := tx.EffectiveGasTip(block.BaseFee())
|
||||||
feesWei.Add(feesWei, new(big.Int).Mul(new(big.Int).SetUint64(receipts[i].GasUsed), minerFee))
|
feesWei.Add(feesWei, new(big.Int).Mul(new(big.Int).SetUint64(receipts[i].GasUsed), minerFee))
|
||||||
}
|
}
|
||||||
return new(big.Float).Quo(new(big.Float).SetInt(feesWei), new(big.Float).SetInt(big.NewInt(params.Ether)))
|
return new(big.Float).Quo(new(big.Float).SetInt(feesWei), new(big.Float).SetInt(big.NewInt(params.Ether)))
|
||||||
|
Loading…
Reference in New Issue
Block a user