Skip to content

Commit ad7ff6d

Browse files
committed
Problem: transient store usage not compatible with parallel tx execution
Currently we use shared transient store keys to accumulate some states, which cause issues when developing parallel tx execution Solution: - remove some transient stores. - the others are used in a per-tx fasion.
1 parent be00d15 commit ad7ff6d

File tree

16 files changed

+165
-96
lines changed

16 files changed

+165
-96
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
4545
* (rpc) [#439](https://github.com/crypto-org-chain/ethermint/pull/439), [#441](https://github.com/crypto-org-chain/ethermint/pull/441) Align trace response for failed tx with go-ethereum.
4646
* (statedb) [#446](https://github.com/crypto-org-chain/ethermint/pull/446) Re-use the cache store implementation with sdk.
4747
* (evm) [#447](https://github.com/crypto-org-chain/ethermint/pull/447) Deduct fee through virtual bank transfer.
48+
* (evm) [#]() Refactor transient stores to be compatible with parallel tx execution.
4849

4950
### State Machine Breaking
5051

app/ante/interfaces.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ type EVMKeeper interface {
3232
ChainID() *big.Int
3333

3434
DeductTxCostsFromUserBalance(ctx sdk.Context, fees sdk.Coins, from common.Address) error
35-
ResetTransientGasUsed(ctx sdk.Context)
36-
GetTxIndexTransient(ctx sdk.Context) uint64
3735
}
3836

3937
type protoTxProvider interface {

app/ante/setup.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,6 @@ func SetupEthContext(ctx sdk.Context, evmKeeper EVMKeeper) (newCtx sdk.Context,
3636
WithKVGasConfig(storetypes.GasConfig{}).
3737
WithTransientKVGasConfig(storetypes.GasConfig{})
3838

39-
// Reset transient gas used to prepare the execution of current cosmos tx.
40-
// Transient gas-used is necessary to sum the gas-used of cosmos tx, when it contains multiple eth msgs.
41-
evmKeeper.ResetTransientGasUsed(ctx)
42-
4339
return newCtx, nil
4440
}
4541

app/app.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ func NewEthermintApp(
314314
bApp.SetVersion(version.Version)
315315
bApp.SetInterfaceRegistry(interfaceRegistry)
316316
bApp.SetTxEncoder(txConfig.TxEncoder())
317+
bApp.SetTxExecutor(DefaultTxExecutor)
317318

318319
keys := storetypes.NewKVStoreKeys(
319320
// SDK keys

app/executor.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package app
2+
3+
import (
4+
"context"
5+
6+
storetypes "cosmossdk.io/store/types"
7+
abci "github.com/cometbft/cometbft/abci/types"
8+
evmtypes "github.com/evmos/ethermint/x/evm/types"
9+
)
10+
11+
func DefaultTxExecutor(_ context.Context,
12+
blockSize int,
13+
ms storetypes.MultiStore,
14+
deliverTxWithMultiStore func(int, storetypes.MultiStore) *abci.ExecTxResult,
15+
) ([]*abci.ExecTxResult, error) {
16+
results := make([]*abci.ExecTxResult, blockSize)
17+
for i := 0; i < blockSize; i++ {
18+
results[i] = deliverTxWithMultiStore(i, ms)
19+
}
20+
return evmtypes.PatchTxResponses(results), nil
21+
}

x/evm/keeper/abci.go

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ import (
1919
"cosmossdk.io/store/types"
2020

2121
sdk "github.com/cosmos/cosmos-sdk/types"
22-
23-
ethtypes "github.com/ethereum/go-ethereum/core/types"
2422
)
2523

2624
// BeginBlock sets the sdk Context and EIP155 chain id to the Keeper.
@@ -35,9 +33,6 @@ func (k *Keeper) BeginBlock(ctx sdk.Context) error {
3533
func (k *Keeper) EndBlock(ctx sdk.Context) error {
3634
// Gas costs are handled within msg handler so costs should be ignored
3735
infCtx := ctx.WithGasMeter(types.NewInfiniteGasMeter())
38-
39-
bloom := ethtypes.BytesToBloom(k.GetBlockBloomTransient(infCtx).Bytes())
40-
k.EmitBlockBloomEvent(infCtx, bloom)
41-
36+
k.CollectTxBloom(infCtx)
4237
return nil
4338
}

x/evm/keeper/bloom.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package keeper
2+
3+
import (
4+
"math/big"
5+
6+
"cosmossdk.io/store/prefix"
7+
sdk "github.com/cosmos/cosmos-sdk/types"
8+
"github.com/evmos/ethermint/x/evm/types"
9+
)
10+
11+
func (k Keeper) SetTxBloom(ctx sdk.Context, bloom []byte) {
12+
store := ctx.KVStore(k.transientKey)
13+
store.Set(types.TransientBloomKey(ctx.TxIndex(), ctx.MsgIndex()), bloom)
14+
}
15+
16+
func (k Keeper) CollectTxBloom(ctx sdk.Context) {
17+
store := prefix.NewStore(ctx.KVStore(k.transientKey), types.KeyPrefixTransientBloom)
18+
it := store.Iterator(nil, nil)
19+
defer it.Close()
20+
21+
bloom := new(big.Int)
22+
for ; it.Valid(); it.Next() {
23+
bloom.Or(bloom, big.NewInt(0).SetBytes(it.Value()))
24+
}
25+
26+
k.EmitBlockBloomEvent(ctx, bloom.Bytes())
27+
}

x/evm/keeper/config.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,7 @@ func (k *Keeper) TxConfig(ctx sdk.Context, txHash common.Hash) statedb.TxConfig
8989
return statedb.NewTxConfig(
9090
common.BytesToHash(ctx.HeaderHash()), // BlockHash
9191
txHash, // TxHash
92-
uint(k.GetTxIndexTransient(ctx)), // TxIndex
93-
uint(k.GetLogSizeTransient(ctx)), // LogIndex
92+
0, 0,
9493
)
9594
}
9695

x/evm/keeper/keeper.go

Lines changed: 4 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,11 @@ func (k Keeper) ChainID() *big.Int {
146146
// ----------------------------------------------------------------------------
147147

148148
// EmitBlockBloomEvent emit block bloom events
149-
func (k Keeper) EmitBlockBloomEvent(ctx sdk.Context, bloom ethtypes.Bloom) {
149+
func (k Keeper) EmitBlockBloomEvent(ctx sdk.Context, bloom []byte) {
150150
ctx.EventManager().EmitEvent(
151151
sdk.NewEvent(
152152
types.EventTypeBlockBloom,
153-
sdk.NewAttribute(types.AttributeKeyEthereumBloom, string(bloom.Bytes())),
153+
sdk.NewAttribute(types.AttributeKeyEthereumBloom, string(bloom)),
154154
),
155155
)
156156
}
@@ -180,49 +180,6 @@ func (k Keeper) SetBlockBloomTransient(ctx sdk.Context, bloom *big.Int) {
180180
store.Set(heightBz, bloom.Bytes())
181181
}
182182

183-
// ----------------------------------------------------------------------------
184-
// Tx
185-
// ----------------------------------------------------------------------------
186-
187-
// SetTxIndexTransient set the index of processing transaction
188-
func (k Keeper) SetTxIndexTransient(ctx sdk.Context, index uint64) {
189-
store := ctx.TransientStore(k.transientKey)
190-
store.Set(types.KeyPrefixTransientTxIndex, sdk.Uint64ToBigEndian(index))
191-
}
192-
193-
// GetTxIndexTransient returns EVM transaction index on the current block.
194-
func (k Keeper) GetTxIndexTransient(ctx sdk.Context) uint64 {
195-
store := ctx.TransientStore(k.transientKey)
196-
bz := store.Get(types.KeyPrefixTransientTxIndex)
197-
if len(bz) == 0 {
198-
return 0
199-
}
200-
201-
return sdk.BigEndianToUint64(bz)
202-
}
203-
204-
// ----------------------------------------------------------------------------
205-
// Log
206-
// ----------------------------------------------------------------------------
207-
208-
// GetLogSizeTransient returns EVM log index on the current block.
209-
func (k Keeper) GetLogSizeTransient(ctx sdk.Context) uint64 {
210-
store := ctx.TransientStore(k.transientKey)
211-
bz := store.Get(types.KeyPrefixTransientLogSize)
212-
if len(bz) == 0 {
213-
return 0
214-
}
215-
216-
return sdk.BigEndianToUint64(bz)
217-
}
218-
219-
// SetLogSizeTransient fetches the current EVM log index from the transient store, increases its
220-
// value by one and then sets the new index back to the transient store.
221-
func (k Keeper) SetLogSizeTransient(ctx sdk.Context, logSize uint64) {
222-
store := ctx.TransientStore(k.transientKey)
223-
store.Set(types.KeyPrefixTransientLogSize, sdk.Uint64ToBigEndian(logSize))
224-
}
225-
226183
// ----------------------------------------------------------------------------
227184
// Storage
228185
// ----------------------------------------------------------------------------
@@ -349,16 +306,10 @@ func (k Keeper) getBaseFee(ctx sdk.Context, london bool) *big.Int {
349306
return baseFee
350307
}
351308

352-
// ResetTransientGasUsed reset gas used to prepare for execution of current cosmos tx, called in ante handler.
353-
func (k Keeper) ResetTransientGasUsed(ctx sdk.Context) {
354-
store := ctx.TransientStore(k.transientKey)
355-
store.Delete(types.KeyPrefixTransientGasUsed)
356-
}
357-
358309
// GetTransientGasUsed returns the gas used by current cosmos tx.
359310
func (k Keeper) GetTransientGasUsed(ctx sdk.Context) uint64 {
360311
store := ctx.TransientStore(k.transientKey)
361-
bz := store.Get(types.KeyPrefixTransientGasUsed)
312+
bz := store.Get(types.TransientGasUsedKey(ctx.TxIndex()))
362313
if len(bz) == 0 {
363314
return 0
364315
}
@@ -369,7 +320,7 @@ func (k Keeper) GetTransientGasUsed(ctx sdk.Context) uint64 {
369320
func (k Keeper) SetTransientGasUsed(ctx sdk.Context, gasUsed uint64) {
370321
store := ctx.TransientStore(k.transientKey)
371322
bz := sdk.Uint64ToBigEndian(gasUsed)
372-
store.Set(types.KeyPrefixTransientGasUsed, bz)
323+
store.Set(types.TransientGasUsedKey(ctx.TxIndex()), bz)
373324
}
374325

375326
// AddTransientGasUsed accumulate gas used by each eth msgs included in current cosmos tx.

x/evm/keeper/msg_server.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t
4444
ctx := sdk.UnwrapSDKContext(goCtx)
4545

4646
tx := msg.AsTransaction()
47-
txIndex := k.GetTxIndexTransient(ctx)
4847

4948
labels := []metrics.Label{
5049
telemetry.NewLabel("tx_type", fmt.Sprintf("%d", tx.Type())),
@@ -92,8 +91,6 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t
9291
sdk.NewAttribute(sdk.AttributeKeyAmount, tx.Value().String()),
9392
// add event for ethereum transaction hash format
9493
sdk.NewAttribute(types.AttributeKeyEthereumTxHash, response.Hash),
95-
// add event for index of valid ethereum tx
96-
sdk.NewAttribute(types.AttributeKeyTxIndex, strconv.FormatUint(txIndex, 10)),
9794
// add event for eth tx gas used, we can't get it from cosmos tx result when it contains multiple eth tx msgs.
9895
sdk.NewAttribute(types.AttributeKeyTxGasUsed, strconv.FormatUint(response.GasUsed, 10)),
9996
}

0 commit comments

Comments
 (0)