mirror of
https://github.com/0glabs/0g-chain.git
synced 2025-04-04 15:55:23 +00:00
Compare commits
No commits in common. "d4066b6a3d74b0d70c7870c17c8af68a1790e9ea" and "ec7e0c31635a95075a38acd88d23e1b94ca54de5" have entirely different histories.
d4066b6a3d
...
ec7e0c3163
@ -5,7 +5,6 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/0glabs/0g-chain/chaincfg"
|
|
||||||
"github.com/cockroachdb/errors"
|
"github.com/cockroachdb/errors"
|
||||||
abci "github.com/cometbft/cometbft/abci/types"
|
abci "github.com/cometbft/cometbft/abci/types"
|
||||||
gethtypes "github.com/ethereum/go-ethereum/core/types"
|
gethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||||
@ -43,13 +42,6 @@ type (
|
|||||||
FeeMarketKeeper interface {
|
FeeMarketKeeper interface {
|
||||||
SetSuggestionGasPrice(ctx sdk.Context, gas *big.Int)
|
SetSuggestionGasPrice(ctx sdk.Context, gas *big.Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
txnInfo struct {
|
|
||||||
gasPrice *big.Int
|
|
||||||
gasLimit uint64
|
|
||||||
nonce uint64
|
|
||||||
sender string
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewDefaultProposalHandler(mp mempool.Mempool, txVerifier ProposalTxVerifier, feemarketKeeper FeeMarketKeeper) *DefaultProposalHandler {
|
func NewDefaultProposalHandler(mp mempool.Mempool, txVerifier ProposalTxVerifier, feemarketKeeper FeeMarketKeeper) *DefaultProposalHandler {
|
||||||
@ -114,7 +106,7 @@ func (h *DefaultProposalHandler) PrepareProposalHandler() sdk.PrepareProposalHan
|
|||||||
return abci.ResponsePrepareProposal{Txs: h.txSelector.SelectedTxs()}
|
return abci.ResponsePrepareProposal{Txs: h.txSelector.SelectedTxs()}
|
||||||
}
|
}
|
||||||
|
|
||||||
txnInfoMap := make(map[string][]*txnInfo, h.mempool.CountTx())
|
gasPriceSlice := make([]*big.Int, 0, h.mempool.CountTx())
|
||||||
|
|
||||||
iterator := h.mempool.Select(ctx, req.Txs)
|
iterator := h.mempool.Select(ctx, req.Txs)
|
||||||
selectedTxsSignersSeqs := make(map[string]uint64)
|
selectedTxsSignersSeqs := make(map[string]uint64)
|
||||||
@ -122,6 +114,17 @@ func (h *DefaultProposalHandler) PrepareProposalHandler() sdk.PrepareProposalHan
|
|||||||
for iterator != nil {
|
for iterator != nil {
|
||||||
memTx := iterator.Tx()
|
memTx := iterator.Tx()
|
||||||
|
|
||||||
|
for _, msg := range memTx.GetMsgs() {
|
||||||
|
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
|
||||||
|
if ok {
|
||||||
|
txData, err := evmtypes.UnpackTxData(msgEthTx.Data)
|
||||||
|
if err == nil {
|
||||||
|
gp := txData.GetGasPrice()
|
||||||
|
gasPriceSlice = append(gasPriceSlice, gp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sigs, err := memTx.(signing.SigVerifiableTx).GetSignaturesV2()
|
sigs, err := memTx.(signing.SigVerifiableTx).GetSignaturesV2()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("failed to get signatures: %w", err))
|
panic(fmt.Errorf("failed to get signatures: %w", err))
|
||||||
@ -154,42 +157,10 @@ func (h *DefaultProposalHandler) PrepareProposalHandler() sdk.PrepareProposalHan
|
|||||||
txSignersSeqs[signer] = nonce
|
txSignersSeqs[signer] = nonce
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, exists := txnInfoMap[signer]; !exists {
|
|
||||||
txnInfoMap[signer] = make([]*txnInfo, 0, 128)
|
|
||||||
}
|
|
||||||
|
|
||||||
txnInfoMap[signer] = append(txnInfoMap[signer], &txnInfo{
|
|
||||||
gasPrice: ethTx.GasPrice(),
|
|
||||||
gasLimit: ethTx.Gas(),
|
|
||||||
nonce: nonce,
|
|
||||||
sender: signer,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// ignore multisig case now
|
|
||||||
fee := memTx.(sdk.Fee)
|
|
||||||
if len(sigs) == 1 {
|
|
||||||
signer := sdk.AccAddress(sigs[0].PubKey.Address()).String()
|
|
||||||
|
|
||||||
if _, exists := txnInfoMap[signer]; !exists {
|
|
||||||
txnInfoMap[signer] = make([]*txnInfo, 0, 16)
|
|
||||||
}
|
|
||||||
|
|
||||||
evmGasPrice, err := utilCosmosDemonGasPriceToEvmDemonGasPrice(fee.GetAmount())
|
|
||||||
|
|
||||||
if err == nil {
|
|
||||||
txnInfoMap[signer] = append(txnInfoMap[signer], &txnInfo{
|
|
||||||
gasPrice: evmGasPrice,
|
|
||||||
gasLimit: utilCosmosDemonGasLimitToEvmDemonGasLimit(fee.GetGas()),
|
|
||||||
nonce: sigs[0].Sequence,
|
|
||||||
sender: signer,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, sig := range sigs {
|
for _, sig := range sigs {
|
||||||
signer := sdk.AccAddress(sig.PubKey.Address()).String()
|
signer := sdk.AccAddress(sig.PubKey.Address()).String()
|
||||||
seq, ok := selectedTxsSignersSeqs[signer]
|
seq, ok := selectedTxsSignersSeqs[signer]
|
||||||
@ -251,54 +222,23 @@ func (h *DefaultProposalHandler) PrepareProposalHandler() sdk.PrepareProposalHan
|
|||||||
iterator = iterator.Next()
|
iterator = iterator.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(txnInfoMap) == 0 {
|
sort.Slice(gasPriceSlice, func(i, j int) bool {
|
||||||
h.feemarketKeeper.SetSuggestionGasPrice(ctx, big.NewInt(0))
|
return gasPriceSlice[i].Cmp(gasPriceSlice[j]) > 0
|
||||||
} else {
|
})
|
||||||
senderCnt := 0
|
|
||||||
txnCnt := 0
|
remaing := gasPriceSuggestionBlockNum * int64(maxBlockGas)
|
||||||
for sender := range txnInfoMap {
|
for _, gp := range gasPriceSlice {
|
||||||
sort.Slice(txnInfoMap[sender], func(i, j int) bool {
|
if remaing <= 0 {
|
||||||
return txnInfoMap[sender][i].nonce < txnInfoMap[sender][j].nonce
|
h.feemarketKeeper.SetSuggestionGasPrice(ctx, gp)
|
||||||
})
|
break
|
||||||
txnCnt += len(txnInfoMap[sender])
|
|
||||||
senderCnt++
|
|
||||||
}
|
}
|
||||||
|
remaing -= gp.Int64()
|
||||||
|
}
|
||||||
|
|
||||||
remaing := gasPriceSuggestionBlockNum * int64(maxBlockGas)
|
if remaing > 0 {
|
||||||
for len(txnInfoMap) > 0 && remaing > 0 {
|
if len(gasPriceSlice) > 0 {
|
||||||
|
h.feemarketKeeper.SetSuggestionGasPrice(ctx, gasPriceSlice[len(gasPriceSlice)-1])
|
||||||
// pop each sender's first continuous decreasing subsequence
|
} else {
|
||||||
txnCnt := 0
|
|
||||||
senderNonceSortedSliceGroup := make([][]*txnInfo, 0, senderCnt)
|
|
||||||
for sender := range txnInfoMap {
|
|
||||||
endIndex := findFirstContinuousDecreasingSubsequence(txnInfoMap[sender])
|
|
||||||
appendSlice := txnInfoMap[sender][:endIndex]
|
|
||||||
senderNonceSortedSliceGroup = append(senderNonceSortedSliceGroup, appendSlice)
|
|
||||||
txnCnt += len(appendSlice)
|
|
||||||
txnInfoMap[sender] = txnInfoMap[sender][endIndex:]
|
|
||||||
if len(txnInfoMap[sender]) == 0 {
|
|
||||||
delete(txnInfoMap, sender)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var gasPriceSortedSlice []*txnInfo
|
|
||||||
if len(senderNonceSortedSliceGroup) > 0 {
|
|
||||||
gasPriceSortedSlice = make([]*txnInfo, 0, len(senderNonceSortedSliceGroup[0]))
|
|
||||||
for i := range senderNonceSortedSliceGroup {
|
|
||||||
gasPriceSortedSlice = mergeSort(len(gasPriceSortedSlice)+len(senderNonceSortedSliceGroup[i]), gasPriceSortedSlice, senderNonceSortedSliceGroup[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := range gasPriceSortedSlice {
|
|
||||||
remaing -= int64(gasPriceSortedSlice[i].gasLimit)
|
|
||||||
if remaing <= 0 {
|
|
||||||
h.feemarketKeeper.SetSuggestionGasPrice(ctx, gasPriceSortedSlice[i].gasPrice)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if remaing > 0 {
|
|
||||||
h.feemarketKeeper.SetSuggestionGasPrice(ctx, big.NewInt(0))
|
h.feemarketKeeper.SetSuggestionGasPrice(ctx, big.NewInt(0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -441,64 +381,3 @@ func (ts *defaultTxSelector) SelectTxForProposal(maxTxBytes, maxBlockGas uint64,
|
|||||||
// check if we've reached capacity; if so, we cannot select any more transactions
|
// check if we've reached capacity; if so, we cannot select any more transactions
|
||||||
return ts.totalTxBytes >= maxTxBytes || (maxBlockGas > 0 && (ts.totalTxGas >= maxBlockGas))
|
return ts.totalTxBytes >= maxTxBytes || (maxBlockGas > 0 && (ts.totalTxGas >= maxBlockGas))
|
||||||
}
|
}
|
||||||
|
|
||||||
func utilCosmosDemonGasPriceToEvmDemonGasPrice(gasGroup sdk.Coins) (*big.Int, error) {
|
|
||||||
gasPrice := big.NewInt(0)
|
|
||||||
for _, coin := range gasGroup {
|
|
||||||
if coin.Denom == chaincfg.GasDenom {
|
|
||||||
thisGasPrice := big.NewInt(0).SetUint64(coin.Amount.Uint64())
|
|
||||||
thisGasPrice = thisGasPrice.Mul(thisGasPrice, big.NewInt(0).SetInt64(chaincfg.GasDenomConversionMultiplier))
|
|
||||||
gasPrice = gasPrice.Add(gasPrice, thisGasPrice)
|
|
||||||
} else {
|
|
||||||
return big.NewInt(0), fmt.Errorf("invalid denom: %s", coin.Denom)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return gasPrice, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func utilCosmosDemonGasLimitToEvmDemonGasLimit(gasLimit uint64) uint64 {
|
|
||||||
return gasLimit * chaincfg.GasDenomConversionMultiplier
|
|
||||||
}
|
|
||||||
|
|
||||||
func findFirstContinuousDecreasingSubsequence(data []*txnInfo) int {
|
|
||||||
ll := len(data)
|
|
||||||
if ll < 2 {
|
|
||||||
return ll
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < ll-1; i++ {
|
|
||||||
if data[i].gasPrice.Cmp(data[i+1].gasPrice) >= 0 {
|
|
||||||
end := i + 1
|
|
||||||
for ; end < ll && data[end-1].gasPrice.Cmp(data[end].gasPrice) > 0; end++ {
|
|
||||||
}
|
|
||||||
if end == ll || data[end-1].gasPrice.Cmp(data[end].gasPrice) <= 0 {
|
|
||||||
return end
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return i + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ll
|
|
||||||
}
|
|
||||||
|
|
||||||
func mergeSort(size int, left, right []*txnInfo) []*txnInfo {
|
|
||||||
result := make([]*txnInfo, 0, size)
|
|
||||||
i, j := 0, 0
|
|
||||||
|
|
||||||
for i < len(left) && j < len(right) {
|
|
||||||
if left[i].gasPrice.Cmp(right[j].gasPrice) > 0 {
|
|
||||||
result = append(result, left[i])
|
|
||||||
i++
|
|
||||||
} else {
|
|
||||||
result = append(result, right[j])
|
|
||||||
j++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result = append(result, left[i:]...)
|
|
||||||
result = append(result, right[j:]...)
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user