Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

optimize the mempool 2 #136

Open
wants to merge 17 commits into
base: dev
Choose a base branch
from
6 changes: 3 additions & 3 deletions cmd/rpcdaemon/commands/zkevm_counters.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ func (zkapi *ZkEvmAPIImpl) EstimateCounters(ctx context.Context, rpcTx *zkevmRPC

smtDepth := smt.GetDepth()

txCounters := vm.NewTransactionCounter(tx, int(smtDepth), uint16(forkId), zkapi.config.Zk.VirtualCountersSmtReduction, false)
txCounters := vm.NewTransactionCounter(tx, int(smtDepth), uint16(forkId), zkapi.config.Zk.VirtualCountersSmtReduction, false, false)
batchCounters := vm.NewBatchCounterCollector(int(smtDepth), uint16(forkId), zkapi.config.Zk.VirtualCountersSmtReduction, false, nil)

_, err = batchCounters.AddNewTransactionCounters(txCounters)
Expand Down Expand Up @@ -369,7 +369,7 @@ func (api *ZkEvmAPIImpl) TraceTransactionCounters(ctx context.Context, hash comm
return err
}

txCounters := vm.NewTransactionCounter(txn, int(smtDepth), uint16(forkId), api.config.Zk.VirtualCountersSmtReduction, false)
txCounters := vm.NewTransactionCounter(txn, int(smtDepth), uint16(forkId), api.config.Zk.VirtualCountersSmtReduction, false, false)
batchCounters := vm.NewBatchCounterCollector(int(smtDepth), uint16(forkId), api.config.Zk.VirtualCountersSmtReduction, false, nil)

if _, err = batchCounters.AddNewTransactionCounters(txCounters); err != nil {
Expand Down Expand Up @@ -551,7 +551,7 @@ func (api *ZkEvmAPIImpl) execTransaction(
msg core.Message
execResult *core.ExecutionResult
)
txCounters := vm.NewTransactionCounter(tx, smtDepth, forkId, api.config.Zk.VirtualCountersSmtReduction, false)
txCounters := vm.NewTransactionCounter(tx, smtDepth, forkId, api.config.Zk.VirtualCountersSmtReduction, false, false)

if _, err = batchCounters.AddNewTransactionCounters(txCounters); err != nil {
return 0, err
Expand Down
32 changes: 23 additions & 9 deletions cmd/txpool/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,18 @@ var (
commitEvery time.Duration

// For X Layer
enableWhiteList bool
whiteList []string
blockList []string
freeClaimGasAddrs []string
gasPriceMultiple uint64
enableFreeGasByNonce bool
freeGasExAddrs []string
freeGasCountPerAddr uint64
freeGasLimit uint64
enableWhiteList bool
whiteList []string
blockList []string
freeClaimGasAddrs []string
gasPriceMultiple uint64
enableFreeGasByNonce bool
freeGasExAddrs []string
freeGasCountPerAddr uint64
freeGasLimit uint64
okPayAccountList []string
okPayGasLimitPerBlock uint64
okPayCounterLimitPercentage uint
)

func init() {
Expand Down Expand Up @@ -99,6 +102,9 @@ func init() {
rootCmd.Flags().StringSliceVar(&freeGasExAddrs, utils.TxPoolFreeGasExAddrs.Name, ethconfig.DeprecatedDefaultTxPoolConfig.FreeGasExAddrs, utils.TxPoolFreeGasExAddrs.Usage)
rootCmd.PersistentFlags().Uint64Var(&freeGasCountPerAddr, utils.TxPoolFreeGasCountPerAddr.Name, ethconfig.DeprecatedDefaultTxPoolConfig.FreeGasCountPerAddr, utils.TxPoolFreeGasCountPerAddr.Usage)
rootCmd.PersistentFlags().Uint64Var(&freeGasLimit, utils.TxPoolFreeGasLimit.Name, ethconfig.DeprecatedDefaultTxPoolConfig.FreeGasLimit, utils.TxPoolFreeGasLimit.Usage)
rootCmd.Flags().Uint64Var(&okPayGasLimitPerBlock, utils.TxPoolOkPayGasLimitPerBlock.Name, 0, utils.TxPoolOkPayGasLimitPerBlock.Usage)
rootCmd.Flags().StringSliceVar(&okPayAccountList, utils.TxPoolOkPayAccountList.Name, []string{}, utils.TxPoolOkPayAccountList.Usage)
rootCmd.Flags().UintVar(&okPayCounterLimitPercentage, utils.TxPoolOkPayCounterLimitPercentage.Name, 50, utils.TxPoolOkPayCounterLimitPercentage.Usage)
}

var rootCmd = &cobra.Command{
Expand Down Expand Up @@ -204,6 +210,14 @@ func doTxpool(ctx context.Context) error {
ethCfg.DeprecatedTxPool.FreeGasCountPerAddr = freeGasCountPerAddr
ethCfg.DeprecatedTxPool.FreeGasLimit = freeGasLimit

ethCfg.DeprecatedTxPool.OkPayAccountList = make([]string, len(okPayAccountList))
for i, addrHex := range okPayAccountList {
addr := common.HexToAddress(addrHex)
ethCfg.DeprecatedTxPool.OkPayAccountList[i] = addr.String()
}
ethCfg.DeprecatedTxPool.OkPayGasLimitPerBlock = okPayGasLimitPerBlock
ethCfg.DeprecatedTxPool.OkPayCounterLimitPercentage = okPayCounterLimitPercentage

newTxs := make(chan types.Announcements, 1024)
defer close(newTxs)
txPoolDB, txPool, fetch, send, txpoolGrpcServer, err := txpooluitl.AllComponents(ctx, cfg, ethCfg,
Expand Down
30 changes: 30 additions & 0 deletions cmd/utils/flags_xlayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,21 @@ var (
Name: "txpool.freegaslimit",
Usage: "FreeGasLimit is the max gas allowed use to do a free gas tx",
}
TxPoolOkPayAccountList = cli.StringFlag{
Name: "txpool.okpay-account-list",
Usage: "Comma separated list of addresses, who send ok pay tx",
Value: "",
}
TxPoolOkPayGasLimitPerBlock = cli.Uint64Flag{
Name: "txpool.okpay-gaslimit-per-block",
Usage: "the block max gas limit for ok pay tx",
Value: 0,
}
TxPoolOkPayCounterLimitPercentage = cli.UintFlag{
Name: "txpool.okpay-counter-limit-percentage",
Usage: "okpaytx's percentage of counter limit",
Value: 50,
}
// Gas Pricer
GpoTypeFlag = cli.StringFlag{
Name: "gpo.type",
Expand Down Expand Up @@ -308,6 +323,21 @@ func setTxPoolXLayer(ctx *cli.Context, cfg *ethconfig.DeprecatedTxPoolConfig) {
if ctx.IsSet(TxPoolFreeGasLimit.Name) {
cfg.FreeGasLimit = ctx.Uint64(TxPoolFreeGasLimit.Name)
}
if ctx.IsSet(TxPoolOkPayAccountList.Name) {
// Parse the command separated flag
addrHexes := SplitAndTrim(ctx.String(TxPoolOkPayAccountList.Name))
cfg.OkPayAccountList = make([]string, len(addrHexes))
for i, senderHex := range addrHexes {
sender := libcommon.HexToAddress(senderHex)
cfg.OkPayAccountList[i] = sender.String()
}
}
if ctx.IsSet(TxPoolOkPayGasLimitPerBlock.Name) {
cfg.OkPayGasLimitPerBlock = ctx.Uint64(TxPoolOkPayGasLimitPerBlock.Name)
}
if ctx.IsSet((TxPoolOkPayCounterLimitPercentage.Name)) {
cfg.OkPayCounterLimitPercentage = ctx.Uint(TxPoolOkPayCounterLimitPercentage.Name)
}
}

// SetApolloGPOXLayer is a public wrapper function to internally call setGPO
Expand Down
22 changes: 22 additions & 0 deletions core/vm/zk_batch_counters.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ type BatchCounterCollector struct {
rlpCombinedCountersCache Counters
executionCombinedCountersCache Counters
processingCombinedCountersCache Counters

// For X Layer
okPayRlpCombinedCounters Counters
okPayExecutionCombinedCounters Counters
okPayProcessingCombinedCounters Counters
}

func NewBatchCounterCollector(smtMaxLevel int, forkId uint16, mcpReduction float64, unlimitedCounters bool, addonCounters *Counters) *BatchCounterCollector {
Expand All @@ -45,6 +50,10 @@ func NewBatchCounterCollector(smtMaxLevel int, forkId uint16, mcpReduction float
bcc.executionCombinedCounters = bcc.NewCounters()
bcc.processingCombinedCounters = bcc.NewCounters()

bcc.okPayRlpCombinedCounters = bcc.NewCounters()
bcc.okPayExecutionCombinedCounters = bcc.NewCounters()
bcc.okPayProcessingCombinedCounters = bcc.NewCounters()

return &bcc
}

Expand Down Expand Up @@ -73,6 +82,10 @@ func (bcc *BatchCounterCollector) Clone() *BatchCounterCollector {
rlpCombinedCounters: bcc.rlpCombinedCounters.Clone(),
executionCombinedCounters: bcc.executionCombinedCounters.Clone(),
processingCombinedCounters: bcc.processingCombinedCounters.Clone(),

okPayRlpCombinedCounters: bcc.okPayRlpCombinedCounters.Clone(),
okPayExecutionCombinedCounters: bcc.okPayExecutionCombinedCounters.Clone(),
okPayProcessingCombinedCounters: bcc.okPayProcessingCombinedCounters.Clone(),
}
}

Expand Down Expand Up @@ -274,15 +287,24 @@ func (bcc *BatchCounterCollector) CombineCollectorsNoChanges() Counters {
func (bcc *BatchCounterCollector) UpdateRlpCountersCache(txCounters *TransactionCounter) {
for k, v := range txCounters.rlpCounters.counters {
bcc.rlpCombinedCounters[k].used += v.used
if txCounters.isOkPayTx {
bcc.okPayRlpCombinedCounters[k].used += v.used
}
}
}

func (bcc *BatchCounterCollector) UpdateExecutionAndProcessingCountersCache(txCounters *TransactionCounter) {
for k, v := range txCounters.executionCounters.counters {
bcc.executionCombinedCounters[k].used += v.used
if txCounters.isOkPayTx {
bcc.okPayExecutionCombinedCounters[k].used += v.used
}
}

for k, v := range txCounters.processingCounters.counters {
bcc.processingCombinedCounters[k].used += v.used
if txCounters.isOkPayTx {
bcc.okPayProcessingCombinedCounters[k].used += v.used
}
}
}
35 changes: 35 additions & 0 deletions core/vm/zk_batch_counters_xlayer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package vm

import (
"fmt"
"github.com/ledgerwatch/log/v3"
)

// CheckOkPayForOverflow returns true in the case that any counter has less than 0 remaining
func (bcc *BatchCounterCollector) CheckOkPayForOverflow(okPayCounterLimitPercentage uint) (bool, error) {
combined := bcc.NewCounters()
for k, _ := range combined {
val := bcc.rlpCombinedCounters[k].used + bcc.executionCombinedCounters[k].used + bcc.processingCombinedCounters[k].used
combined[k].used += val
combined[k].remaining -= val
}

overflow := false
for _, v := range combined {
if v.initialAmount*int(okPayCounterLimitPercentage)/100 < v.used {
log.Info("[VCOUNTER] OkPay Counter overflow detected", "counter", v.name, "remaining", v.remaining, "used", v.used)
overflow = true
}
}

// if we have an overflow we want to log the counters for debugging purposes
if overflow {
logText := "[VCOUNTER] Counters stats"
for _, v := range combined {
logText += fmt.Sprintf(" %s: initial: %v used: %v (remaining: %v)", v.name, v.initialAmount, v.used, v.remaining)
}
log.Info(logText)
}

return overflow, nil
}
6 changes: 5 additions & 1 deletion core/vm/zk_transaction_counters.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ type TransactionCounter struct {
smtLevels int
forkId uint16
l2DataCache []byte

isOkPayTx bool // For X Layer
}

func NewTransactionCounter(transaction types.Transaction, smtMaxLevel int, forkId uint16, mcpReduction float64, shouldCountersBeUnlimited bool) *TransactionCounter {
func NewTransactionCounter(transaction types.Transaction, smtMaxLevel int, forkId uint16, mcpReduction float64, shouldCountersBeUnlimited bool, isOkPayTx bool) *TransactionCounter {
totalLevel := calculateSmtLevels(smtMaxLevel, 32, mcpReduction)

var tc *TransactionCounter
Expand All @@ -33,6 +35,7 @@ func NewTransactionCounter(transaction types.Transaction, smtMaxLevel int, forkI
processingCounters: NewUnlimitedCounterCollector(),
smtLevels: 1, // max depth of the tree anyways
forkId: forkId,
isOkPayTx: isOkPayTx,
}
} else {
tc = &TransactionCounter{
Expand All @@ -42,6 +45,7 @@ func NewTransactionCounter(transaction types.Transaction, smtMaxLevel int, forkI
processingCounters: NewCounterCollector(totalLevel, forkId),
smtLevels: totalLevel,
forkId: forkId,
isOkPayTx: isOkPayTx,
}
}
tc.executionCounters.SetTransaction(transaction)
Expand Down
6 changes: 6 additions & 0 deletions eth/ethconfig/tx_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ type DeprecatedTxPoolConfig struct {
FreeGasCountPerAddr uint64
// FreeGasLimit is the max gas allowed use to do a free gas tx
FreeGasLimit uint64
// okPayAccountList is the ok pay bundler accounts address
OkPayAccountList []string
// OkPayGasLimitPerBlock is the block max gas limit for ok pay tx
OkPayGasLimitPerBlock uint64
// OkPayCounterLimitPercentage is okpaytx's percentage of counter limit
OkPayCounterLimitPercentage uint
}

// DeprecatedDefaultTxPoolConfig contains the default configurations for the transaction
Expand Down
2 changes: 1 addition & 1 deletion eth/stagedsync/stage_mining_exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ func getNextTransactions(
counter := 0
for !onTime && counter < 1000 {
remainingGas := header.GasLimit - header.GasUsed
if onTime, count, err = cfg.txPool2.YieldBest(amount, &txSlots, poolTx, executionAt, remainingGas, alreadyYielded); err != nil {
if onTime, count, err = cfg.txPool2.YieldBest(amount, &txSlots, poolTx, executionAt, remainingGas, alreadyYielded, false); err != nil {
return err
}
time.Sleep(1 * time.Millisecond)
Expand Down
3 changes: 3 additions & 0 deletions test/config/test.erigon.seq.config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ txpool.gaspricemultiple : 2
txpool.blockedlist: ["0xdD2FD4581271e230360230F9337D5c0430Bf44C0"]
txpool.enablefreegasbynonce : true
txpool.freegascountperaddr : 100
txpool.okpay-gaslimit-per-block: 100000
txpool.okpay-counter-limit-percentage: 80
txpool.okpay-account-list: ["0x36710Da8612C168702bf4F10f5ff089147a1Ba78"]

gpo.type: "follower"
gpo.update-period: "2s"
Expand Down
58 changes: 58 additions & 0 deletions test/e2e/smoke_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -493,3 +493,61 @@ func sendBridgeAsset(
const txTimeout = 60 * time.Second
return operations.WaitTxToBeMined(ctx, c, tx, txTimeout)
}

var (
okPayAddr = "0x36710Da8612C168702bf4F10f5ff089147a1Ba78"
okPayPriKey = "5f329974c35134e12a3b68c3ca1c3f52d96c70f11fae0b0074188067a8906064"
)

func TestOkPayTx(t *testing.T) {
ctx := context.Background()
client, err := ethclient.Dial(operations.DefaultL2NetworkURL)
require.NoError(t, err)

//prepare balance for okPayAddr
transToken(t, ctx, client, uint256.NewInt(21000000*encoding.Gwei), okPayAddr)

// build and send ok pay tx
okPayTx := buildAndSendTransTokenTx(t, ctx, client, okPayPriKey, operations.DefaultL2AdminAddress, uint256.NewInt(0))
err = operations.WaitTxToBeMined(ctx, client, okPayTx, operations.DefaultTimeoutTxToBeMined)
require.NoError(t, err)
//require.Error(t, err, "context deadline exceeded") // txpool.okpay-counter-limit-percentage=0
}

func buildAndSendTransTokenTx(t *testing.T, ctx context.Context, client *ethclient.Client, privateKeyStr string, toAddress string, amount *uint256.Int) types.Transaction {
auth, err := operations.GetAuth(privateKeyStr, operations.DefaultL2ChainID)
nonce, err := client.PendingNonceAt(ctx, auth.From)
//gasPrice, err := client.SuggestGasPrice(ctx)
gasPrice, err := operations.GetMinGasPrice()
require.NoError(t, err)

to := common.HexToAddress(toAddress)
gas, err := client.EstimateGas(ctx, ethereum.CallMsg{
From: auth.From,
To: &to,
Value: amount,
})
require.NoError(t, err)

var tx types.Transaction = &types.LegacyTx{
CommonTx: types.CommonTx{
Nonce: nonce,
To: &to,
Gas: gas,
Value: amount,
},
GasPrice: uint256.NewInt(gasPrice),
}

privateKey, err := crypto.HexToECDSA(strings.TrimPrefix(privateKeyStr, "0x"))
require.NoError(t, err)

signer := types.MakeSigner(operations.GetTestChainConfig(operations.DefaultL2ChainID), 1)
signedTx, err := types.SignTx(tx, *signer, privateKey)
require.NoError(t, err)

err = client.SendTransaction(ctx, signedTx)
require.NoError(t, err)

return signedTx
}
17 changes: 17 additions & 0 deletions test/operations/rpc_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,23 @@ func GetBlockByHash(hash common.Hash) (*types.Block, error) {
return &result, nil
}

func GetBlockByNumber(number *big.Int) (*types.Block, error) {
response, err := client.JSONRPCCall(DefaultL2NetworkURL, "eth_getBlockByNumber", hex.EncodeBig(number), false)
if err != nil {
return nil, err
}
if response.Error != nil {
return nil, fmt.Errorf("%d - %s", response.Error.Code, response.Error.Message)
}
result := types.Block{}
err = json.Unmarshal(response.Result, &result)
if err != nil {
return nil, err
}

return &result, nil
}

func GetInternalTransactions(hash common.Hash) ([]zktypes.InnerTx, error) {
response, err := client.JSONRPCCall(DefaultL2NetworkURL, "eth_getInternalTransactions", hash)
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions turbo/cli/default_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,4 +272,7 @@ var DefaultFlags = []cli.Flag{
&utils.TxPoolFreeGasLimit,
&utils.HTTPApiKeysFlag,
&utils.MethodRateLimitFlag,
&utils.TxPoolOkPayAccountList,
&utils.TxPoolOkPayGasLimitPerBlock,
&utils.TxPoolOkPayCounterLimitPercentage,
}
4 changes: 2 additions & 2 deletions turbo/transactions/call.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,12 +256,12 @@ func NewReusableCaller(
msg.GasPrice(),
msg.Data(),
)

var batchCounters *vm.BatchCounterCollector
var counterCollector *vm.CounterCollector
if useCounters {
batchCounters = vm.NewBatchCounterCollector(smtDepth, uint16(forkId), VirtualCountersSmtReduction, false, nil)
txCounters := vm.NewTransactionCounter(transaction, smtDepth, uint16(forkId), VirtualCountersSmtReduction, false)
txCounters := vm.NewTransactionCounter(transaction, smtDepth, uint16(forkId), VirtualCountersSmtReduction, false, false)

_, err = batchCounters.AddNewTransactionCounters(txCounters)
if err != nil {
Expand Down
Loading