From 8d5050c118efe6435dccf249c6a2b38130abee6c Mon Sep 17 00:00:00 2001 From: andyzhang2023 Date: Wed, 7 Aug 2024 14:24:01 +0800 Subject: [PATCH 1/6] optimize the memory allocation of effectiveGasTipValue() --- core/types/transaction.go | 20 +++++++++++++++----- objs/objpool.go | 14 ++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 objs/objpool.go diff --git a/core/types/transaction.go b/core/types/transaction.go index d7860b57bd..5b86e65edf 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -29,6 +29,7 @@ import ( "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/objs" "github.com/ethereum/go-ethereum/rlp" ) @@ -446,18 +447,27 @@ func (tx *Transaction) EffectiveGasTipCmp(other *Transaction, baseFee *big.Int) } // the EffectiveGasTipValue() always copies two big.Int, which cost almost 90% cpu resource of the whole function, // so we define an alternative function to improve the performance. - return effectiveGasTipValue(tx, baseFee).Cmp(effectiveGasTipValue(other, baseFee)) + effTx, recycleTx := effectiveGasTipValue(tx, baseFee) + effOther, recycleOther := effectiveGasTipValue(other, baseFee) + defer func() { + recycleTx() + recycleOther() + }() + return effTx.Cmp(effOther) } -func effectiveGasTipValue(tx *Transaction, baseFee *big.Int) *big.Int { +func effectiveGasTipValue(tx *Transaction, baseFee *big.Int) (*big.Int, func()) { if tx.Type() == DepositTxType { - return new(big.Int) + newInt := objs.BigIntPool.Get().(*big.Int) + newInt.SetUint64(0) + return new(big.Int), func() { objs.BigIntPool.Put(newInt) } } if baseFee == nil { - return tx.inner.gasTipCap() + return tx.inner.gasTipCap(), func() {} } gasFeeCap := tx.inner.gasFeeCap() - return math.BigMin(tx.inner.gasTipCap(), new(big.Int).Sub(gasFeeCap, baseFee)) + temp := objs.BigIntPool.Get().(*big.Int).Sub(gasFeeCap, baseFee) + return math.BigMin(tx.inner.gasTipCap(), temp), func() { objs.BigIntPool.Put(temp) } } // EffectiveGasTipIntCmp compares the effective gasTipCap of a transaction to the given gasTipCap. diff --git a/objs/objpool.go b/objs/objpool.go new file mode 100644 index 0000000000..301a0a63c9 --- /dev/null +++ b/objs/objpool.go @@ -0,0 +1,14 @@ +package objs + +import ( + "math/big" + "sync" +) + +var ( + BigIntPool = sync.Pool{ + New: func() any { + return new(big.Int) + }, + } +) From d38140105d3825b823b5b1a0ebc5858907391c8e Mon Sep 17 00:00:00 2001 From: andyzhang2023 Date: Wed, 7 Aug 2024 14:55:09 +0800 Subject: [PATCH 2/6] optimize the memory allocation of effectiveGasTipValue() --- core/types/transaction.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/types/transaction.go b/core/types/transaction.go index 5b86e65edf..ca2d272fff 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -460,7 +460,7 @@ func effectiveGasTipValue(tx *Transaction, baseFee *big.Int) (*big.Int, func()) if tx.Type() == DepositTxType { newInt := objs.BigIntPool.Get().(*big.Int) newInt.SetUint64(0) - return new(big.Int), func() { objs.BigIntPool.Put(newInt) } + return newInt, func() { objs.BigIntPool.Put(newInt) } } if baseFee == nil { return tx.inner.gasTipCap(), func() {} From e465a2f9732202644e9cb5dcc6dcb5dbd4172aa7 Mon Sep 17 00:00:00 2001 From: andyzhang2023 Date: Wed, 7 Aug 2024 16:30:00 +0800 Subject: [PATCH 3/6] optimize the memory allocation of *Transaction.Cost() --- core/types/transaction.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/core/types/transaction.go b/core/types/transaction.go index ca2d272fff..c5bb54de8e 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -363,11 +363,14 @@ func (tx *Transaction) IsSystemTx() bool { // Cost returns (gas * gasPrice) + (blobGas * blobGasPrice) + value. func (tx *Transaction) Cost() *big.Int { - total := new(big.Int).Mul(tx.GasPrice(), new(big.Int).SetUint64(tx.Gas())) + gasPrice := tx.inner.gasPrice() + gas := objs.BigIntPool.Get().(*big.Int).SetUint64(tx.Gas()) + total := new(big.Int).Mul(gasPrice, gas) if tx.Type() == BlobTxType { total.Add(total, new(big.Int).Mul(tx.BlobGasFeeCap(), new(big.Int).SetUint64(tx.BlobGas()))) } - total.Add(total, tx.Value()) + objs.BigIntPool.Put(gas) + total.Add(total, tx.inner.value()) return total } From a3a80ec614dff33b37d47409ffd7e0c9cfea91e4 Mon Sep 17 00:00:00 2001 From: andyzhang2023 Date: Wed, 7 Aug 2024 14:35:21 +0800 Subject: [PATCH 4/6] optimize the memory allocation of newL1CostFuncEcotone() --- core/types/rollup_cost.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/core/types/rollup_cost.go b/core/types/rollup_cost.go index e0bc26d92f..f784326267 100644 --- a/core/types/rollup_cost.go +++ b/core/types/rollup_cost.go @@ -24,6 +24,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/objs" "github.com/ethereum/go-ethereum/params" ) @@ -226,17 +227,23 @@ func newL1CostFuncEcotone(l1BaseFee, l1BlobBaseFee, l1BaseFeeScalar, l1BlobBaseF // // calldataGas*(l1BaseFee*16*l1BaseFeeScalar + l1BlobBaseFee*l1BlobBaseFeeScalar)/16e6 - calldataCostPerByte := new(big.Int).Set(l1BaseFee) + calldataCostPerByte := objs.BigIntPool.Get().(*big.Int) + calldataCostPerByte = calldataCostPerByte.Set(l1BaseFee) calldataCostPerByte = calldataCostPerByte.Mul(calldataCostPerByte, sixteen) calldataCostPerByte = calldataCostPerByte.Mul(calldataCostPerByte, l1BaseFeeScalar) - blobCostPerByte := new(big.Int).Set(l1BlobBaseFee) + blobCostPerByte := objs.BigIntPool.Get().(*big.Int) + blobCostPerByte = blobCostPerByte.Set(l1BlobBaseFee) blobCostPerByte = blobCostPerByte.Mul(blobCostPerByte, l1BlobBaseFeeScalar) fee = new(big.Int).Add(calldataCostPerByte, blobCostPerByte) fee = fee.Mul(fee, calldataGasUsed) fee = fee.Div(fee, ecotoneDivisor) + // recycle the two big.Int + objs.BigIntPool.Put(calldataCostPerByte) + objs.BigIntPool.Put(blobCostPerByte) + return fee, calldataGasUsed } } From fb918ca7adabd64fc37b3e8a8a5f9f810c158b8c Mon Sep 17 00:00:00 2001 From: andyzhang2023 Date: Wed, 7 Aug 2024 18:27:53 +0800 Subject: [PATCH 5/6] optimize SubmitTransaction API --- core/types/transaction.go | 11 +++++++++++ internal/ethapi/api.go | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/core/types/transaction.go b/core/types/transaction.go index c5bb54de8e..0301592e66 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -308,6 +308,17 @@ func (tx *Transaction) GasFeeCap() *big.Int { return new(big.Int).Set(tx.inner.g // Value returns the ether amount of the transaction. func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.inner.value()) } +// Value returns the ether amount of the transaction. +func (tx *Transaction) ValueRef() *big.Int { return tx.inner.value() } + +// GasTipCap returns the gasTipCap per gas of the transaction. +func (tx *Transaction) GasTipCapRef() *big.Int { return tx.inner.gasTipCap() } + +// GasFeeCap returns the fee cap per gas of the transaction. +func (tx *Transaction) GasFeeCapRef() *big.Int { return tx.inner.gasFeeCap() } + +func (tx *Transaction) GasPriceRef() *big.Int { return tx.inner.gasPrice() } + // Nonce returns the sender account nonce of the transaction. func (tx *Transaction) Nonce() uint64 { return tx.inner.nonce() } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 02fb0fdb7d..a44faa4464 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -2000,9 +2000,9 @@ func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (c if tx.To() == nil { addr := crypto.CreateAddress(from, tx.Nonce()) - log.Info("Submitted contract creation", "hash", tx.Hash().Hex(), "from", from, "nonce", tx.Nonce(), "contract", addr.Hex(), "value", tx.Value()) + log.Info("Submitted contract creation", "hash", tx.Hash().Hex(), "from", from, "nonce", tx.Nonce(), "contract", addr.Hex(), "value", tx.ValueRef()) } else { - log.Info("Submitted transaction", "hash", tx.Hash().Hex(), "from", from, "nonce", tx.Nonce(), "recipient", tx.To(), "value", tx.Value()) + log.Info("Submitted transaction", "hash", tx.Hash().Hex(), "from", from, "nonce", tx.Nonce(), "recipient", tx.To(), "value", tx.ValueRef()) } return tx.Hash(), nil } From 40b966a2e685f01a5e9ee60caa2db56f93d730ad Mon Sep 17 00:00:00 2001 From: andyzhang2023 Date: Wed, 7 Aug 2024 18:51:35 +0800 Subject: [PATCH 6/6] optimize buyGas() --- core/state_transition.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/core/state_transition.go b/core/state_transition.go index a23a26468e..271663d522 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -27,6 +27,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto/kzg4844" + "github.com/ethereum/go-ethereum/objs" "github.com/ethereum/go-ethereum/params" "github.com/holiman/uint256" ) @@ -247,7 +248,8 @@ func (st *StateTransition) to() common.Address { } func (st *StateTransition) buyGas() error { - mgval := new(big.Int).SetUint64(st.msg.GasLimit) + mgval := objs.BigIntPool.Get().(*big.Int).SetUint64(st.msg.GasLimit) + defer objs.BigIntPool.Put(mgval) mgval = mgval.Mul(mgval, st.msg.GasPrice) var l1Cost *big.Int if st.evm.Context.L1CostFunc != nil && !st.msg.SkipAccountChecks { @@ -260,7 +262,8 @@ func (st *StateTransition) buyGas() error { mgval = mgval.Add(mgval, l1Cost) } } - balanceCheck := new(big.Int).Set(mgval) + balanceCheck := objs.BigIntPool.Get().(*big.Int).Set(mgval) + defer objs.BigIntPool.Put(balanceCheck) if st.msg.GasFeeCap != nil { balanceCheck.SetUint64(st.msg.GasLimit) balanceCheck = balanceCheck.Mul(balanceCheck, st.msg.GasFeeCap) @@ -272,7 +275,8 @@ func (st *StateTransition) buyGas() error { if st.evm.ChainConfig().IsCancun(st.evm.Context.BlockNumber, st.evm.Context.Time) { if blobGas := st.blobGasUsed(); blobGas > 0 { // Check that the user has enough funds to cover blobGasUsed * tx.BlobGasFeeCap - blobBalanceCheck := new(big.Int).SetUint64(blobGas) + blobBalanceCheck := objs.BigIntPool.Get().(*big.Int).SetUint64(blobGas) + defer objs.BigIntPool.Put(blobBalanceCheck) blobBalanceCheck.Mul(blobBalanceCheck, st.msg.BlobGasFeeCap) balanceCheck.Add(balanceCheck, blobBalanceCheck) // Pay for blobGasUsed * actual blob fee