Skip to content

Commit c618235

Browse files
committed
block-stm integration
- patch tx response to fix tx index and log index - collect tx fee to temporary module account
1 parent 41e81d6 commit c618235

File tree

24 files changed

+413
-223
lines changed

24 files changed

+413
-223
lines changed

app/ante/handler_options.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ func newEthAnteHandler(ctx sdk.Context, options HandlerOptions, extra ...sdk.Ant
8686
NewEthGasConsumeDecorator(options.EvmKeeper, options.MaxTxGasWanted, ethCfg, evmDenom, baseFee),
8787
NewEthIncrementSenderSequenceDecorator(options.AccountKeeper), // innermost AnteDecorator.
8888
NewGasWantedDecorator(options.FeeMarketKeeper, ethCfg),
89-
NewEthEmitEventDecorator(options.EvmKeeper), // emit eth tx hash and index at the very last ante handler.
9089
}
9190
decorators = append(decorators, extra...)
9291
return sdk.ChainAnteDecorators(decorators...)

app/ante/interfaces.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ type EVMKeeper interface {
4141
DynamicFeeEVMKeeper
4242

4343
DeductTxCostsFromUserBalance(ctx sdk.Context, fees sdk.Coins, from common.Address) error
44-
ResetTransientGasUsed(ctx sdk.Context)
45-
GetTxIndexTransient(ctx sdk.Context) uint64
4644
}
4745

4846
type protoTxProvider interface {

app/ante/setup.go

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package ante
1818
import (
1919
"errors"
2020
"math/big"
21-
"strconv"
2221

2322
errorsmod "cosmossdk.io/errors"
2423
sdkmath "cosmossdk.io/math"
@@ -53,46 +52,9 @@ func (esc EthSetupContextDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simul
5352
newCtx = ctx.WithGasMeter(storetypes.NewInfiniteGasMeter()).
5453
WithKVGasConfig(storetypes.GasConfig{}).
5554
WithTransientKVGasConfig(storetypes.GasConfig{})
56-
57-
// Reset transient gas used to prepare the execution of current cosmos tx.
58-
// Transient gas-used is necessary to sum the gas-used of cosmos tx, when it contains multiple eth msgs.
59-
esc.evmKeeper.ResetTransientGasUsed(ctx)
6055
return next(newCtx, tx, simulate)
6156
}
6257

63-
// EthEmitEventDecorator emit events in ante handler in case of tx execution failed (out of block gas limit).
64-
type EthEmitEventDecorator struct {
65-
evmKeeper EVMKeeper
66-
}
67-
68-
// NewEthEmitEventDecorator creates a new EthEmitEventDecorator
69-
func NewEthEmitEventDecorator(evmKeeper EVMKeeper) EthEmitEventDecorator {
70-
return EthEmitEventDecorator{evmKeeper}
71-
}
72-
73-
// AnteHandle emits some basic events for the eth messages
74-
func (eeed EthEmitEventDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
75-
// After eth tx passed ante handler, the fee is deducted and nonce increased, it shouldn't be ignored by json-rpc,
76-
// we need to emit some basic events at the very end of ante handler to be indexed by tendermint.
77-
txIndex := eeed.evmKeeper.GetTxIndexTransient(ctx)
78-
for i, msg := range tx.GetMsgs() {
79-
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
80-
if !ok {
81-
return ctx, errorsmod.Wrapf(errortypes.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil))
82-
}
83-
84-
// emit ethereum tx hash as an event so that it can be indexed by Tendermint for query purposes
85-
// it's emitted in ante handler, so we can query failed transaction (out of block gas limit).
86-
ctx.EventManager().EmitEvent(sdk.NewEvent(
87-
evmtypes.EventTypeEthereumTx,
88-
sdk.NewAttribute(evmtypes.AttributeKeyEthereumTxHash, msgEthTx.Hash),
89-
sdk.NewAttribute(evmtypes.AttributeKeyTxIndex, strconv.FormatUint(txIndex+uint64(i), 10)),
90-
))
91-
}
92-
93-
return next(ctx, tx, simulate)
94-
}
95-
9658
// EthValidateBasicDecorator is adapted from ValidateBasicDecorator from cosmos-sdk, it ignores ErrNoSignatures
9759
type EthValidateBasicDecorator struct {
9860
evmParams *evmtypes.Params

app/app.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"net/http"
2424
"os"
2525
"path/filepath"
26+
"sort"
2627

2728
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
2829
reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1"
@@ -392,6 +393,16 @@ func NewEthermintApp(
392393
memKeys: memKeys,
393394
}
394395

396+
app.SetDisableBlockGasMeter(true)
397+
398+
executor := cast.ToString(appOpts.Get(srvflags.EVMBlockExecutor))
399+
if executor == "block-stm" {
400+
workers := cast.ToInt(appOpts.Get(srvflags.EVMBlockSTMWorkers))
401+
app.SetTxExecutor(STMTxExecutor(app.GetStoreKeys(), workers))
402+
} else {
403+
app.SetTxExecutor(DefaultTxExecutor)
404+
}
405+
395406
// init params keeper and subspaces
396407
app.ParamsKeeper = initParamsKeeper(appCodec, cdc, keys[paramstypes.StoreKey], tkeys[paramstypes.TStoreKey])
397408

@@ -1030,6 +1041,22 @@ func (app *EthermintApp) GetMemKey(storeKey string) *storetypes.MemoryStoreKey {
10301041
return app.memKeys[storeKey]
10311042
}
10321043

1044+
// GetStoreKeys returns all the stored store keys.
1045+
func (app *EthermintApp) GetStoreKeys() []storetypes.StoreKey {
1046+
keys := make([]storetypes.StoreKey, 0, len(app.keys))
1047+
for _, key := range app.keys {
1048+
keys = append(keys, key)
1049+
}
1050+
for _, key := range app.tkeys {
1051+
keys = append(keys, key)
1052+
}
1053+
for _, key := range app.memKeys {
1054+
keys = append(keys, key)
1055+
}
1056+
sort.SliceStable(keys, func(i, j int) bool { return keys[i].Name() < keys[j].Name() })
1057+
return keys
1058+
}
1059+
10331060
// GetSubspace returns a param subspace for a given module name.
10341061
//
10351062
// NOTE: This is solely to be used for testing purposes.

app/executor.go

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
package app
2+
3+
import (
4+
"context"
5+
"io"
6+
7+
"cosmossdk.io/store/cachekv"
8+
"cosmossdk.io/store/cachemulti"
9+
"cosmossdk.io/store/tracekv"
10+
storetypes "cosmossdk.io/store/types"
11+
abci "github.com/cometbft/cometbft/abci/types"
12+
"github.com/cosmos/cosmos-sdk/baseapp"
13+
evmtypes "github.com/evmos/ethermint/x/evm/types"
14+
block_stm "github.com/yihuang/go-block-stm"
15+
)
16+
17+
func DefaultTxExecutor(ctx context.Context,
18+
blockSize int,
19+
ms storetypes.MultiStore,
20+
deliverTxWithMultiStore func(int, storetypes.MultiStore) *abci.ExecTxResult,
21+
) ([]*abci.ExecTxResult, error) {
22+
results := make([]*abci.ExecTxResult, blockSize)
23+
for i := 0; i < blockSize; i++ {
24+
results[i] = deliverTxWithMultiStore(i, ms)
25+
}
26+
return evmtypes.PatchTxResponses(results), nil
27+
}
28+
29+
func STMTxExecutor(stores []storetypes.StoreKey, workers int) baseapp.TxExecutor {
30+
return func(
31+
ctx context.Context,
32+
blockSize int,
33+
ms storetypes.MultiStore,
34+
deliverTxWithMultiStore func(int, storetypes.MultiStore) *abci.ExecTxResult,
35+
) ([]*abci.ExecTxResult, error) {
36+
if blockSize == 0 {
37+
return nil, nil
38+
}
39+
results := make([]*abci.ExecTxResult, blockSize)
40+
if err := block_stm.ExecuteBlock(
41+
ctx,
42+
blockSize,
43+
stores,
44+
stmMultiStoreWrapper{ms},
45+
workers,
46+
func(txn block_stm.TxnIndex, ms block_stm.MultiStore) {
47+
result := deliverTxWithMultiStore(int(txn), newMultiStoreWrapper(ms, stores))
48+
results[txn] = result
49+
},
50+
); err != nil {
51+
return nil, err
52+
}
53+
54+
return evmtypes.PatchTxResponses(results), nil
55+
}
56+
}
57+
58+
type storeWrapper struct {
59+
block_stm.KVStore
60+
}
61+
62+
var (
63+
_ storetypes.Store = storeWrapper{}
64+
_ storetypes.KVStore = storeWrapper{}
65+
)
66+
67+
func (s storeWrapper) GetStoreType() storetypes.StoreType {
68+
return storetypes.StoreTypeIAVL
69+
}
70+
71+
func (s storeWrapper) CacheWrap() storetypes.CacheWrap {
72+
return cachekv.NewStore(storetypes.KVStore(s))
73+
}
74+
75+
func (s storeWrapper) CacheWrapWithTrace(w io.Writer, tc storetypes.TraceContext) storetypes.CacheWrap {
76+
return cachekv.NewStore(tracekv.NewStore(s, w, tc))
77+
}
78+
79+
type msWrapper struct {
80+
block_stm.MultiStore
81+
stores []storetypes.StoreKey
82+
keysByName map[string]storetypes.StoreKey
83+
}
84+
85+
var _ storetypes.MultiStore = msWrapper{}
86+
87+
func newMultiStoreWrapper(ms block_stm.MultiStore, stores []storetypes.StoreKey) msWrapper {
88+
keysByName := make(map[string]storetypes.StoreKey)
89+
for _, k := range stores {
90+
keysByName[k.Name()] = k
91+
}
92+
return msWrapper{ms, stores, keysByName}
93+
}
94+
95+
func (ms msWrapper) GetStore(key storetypes.StoreKey) storetypes.Store {
96+
return storetypes.Store(ms.GetKVStore(key))
97+
}
98+
99+
func (ms msWrapper) GetKVStore(key storetypes.StoreKey) storetypes.KVStore {
100+
return storeWrapper{ms.MultiStore.GetKVStore(key)}
101+
}
102+
103+
func (ms msWrapper) CacheMultiStore() storetypes.CacheMultiStore {
104+
stores := make(map[storetypes.StoreKey]storetypes.CacheWrapper)
105+
for _, k := range ms.stores {
106+
store := ms.GetKVStore(k)
107+
stores[k] = store
108+
}
109+
return cachemulti.NewStore(nil, stores, ms.keysByName, nil, nil)
110+
}
111+
112+
func (ms msWrapper) CacheMultiStoreWithVersion(_ int64) (storetypes.CacheMultiStore, error) {
113+
panic("cannot branch cached multi-store with a version")
114+
}
115+
116+
// Implements CacheWrapper.
117+
func (ms msWrapper) CacheWrap() storetypes.CacheWrap {
118+
return ms.CacheMultiStore().(storetypes.CacheWrap)
119+
}
120+
121+
// CacheWrapWithTrace implements the CacheWrapper interface.
122+
func (ms msWrapper) CacheWrapWithTrace(_ io.Writer, _ storetypes.TraceContext) storetypes.CacheWrap {
123+
return ms.CacheWrap()
124+
}
125+
126+
// GetStoreType returns the type of the store.
127+
func (ms msWrapper) GetStoreType() storetypes.StoreType {
128+
return storetypes.StoreTypeMulti
129+
}
130+
131+
// LatestVersion returns the branch version of the store
132+
func (ms msWrapper) LatestVersion() int64 {
133+
panic("cannot get latest version from branch cached multi-store")
134+
}
135+
136+
// Implements interface MultiStore
137+
func (ms msWrapper) SetTracer(w io.Writer) storetypes.MultiStore {
138+
return nil
139+
}
140+
141+
// Implements interface MultiStore
142+
func (ms msWrapper) SetTracingContext(storetypes.TraceContext) storetypes.MultiStore {
143+
return nil
144+
}
145+
146+
// Implements interface MultiStore
147+
func (ms msWrapper) TracingEnabled() bool {
148+
return false
149+
}
150+
151+
type stmMultiStoreWrapper struct {
152+
inner storetypes.MultiStore
153+
}
154+
155+
var _ block_stm.MultiStore = stmMultiStoreWrapper{}
156+
157+
func (ms stmMultiStoreWrapper) GetKVStore(key storetypes.StoreKey) block_stm.KVStore {
158+
return block_stm.KVStore(ms.inner.GetKVStore(key))
159+
}

go.mod

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ require (
3131
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
3232
github.com/ethereum/go-ethereum v1.10.26
3333
github.com/gogo/protobuf v1.3.2
34-
github.com/golang/protobuf v1.5.3
34+
github.com/golang/protobuf v1.5.4
3535
github.com/gorilla/mux v1.8.1
3636
github.com/gorilla/websocket v1.5.1
3737
github.com/grpc-ecosystem/grpc-gateway v1.16.0
@@ -50,12 +50,13 @@ require (
5050
github.com/tidwall/gjson v1.14.4
5151
github.com/tidwall/sjson v1.2.5
5252
github.com/tyler-smith/go-bip39 v1.1.0
53+
github.com/yihuang/go-block-stm v0.0.0-20240304045905-48d16c0e4681
5354
golang.org/x/net v0.21.0
5455
golang.org/x/sync v0.6.0
5556
golang.org/x/text v0.14.0
5657
google.golang.org/genproto/googleapis/api v0.0.0-20240205150955-31a09d347014
5758
google.golang.org/grpc v1.62.0
58-
google.golang.org/protobuf v1.32.0
59+
google.golang.org/protobuf v1.33.0
5960
sigs.k8s.io/yaml v1.4.0
6061
)
6162

@@ -220,12 +221,12 @@ require (
220221
go.opentelemetry.io/otel/metric v1.22.0 // indirect
221222
go.opentelemetry.io/otel/trace v1.22.0 // indirect
222223
go.uber.org/multierr v1.11.0 // indirect
223-
golang.org/x/crypto v0.21.0 // indirect
224+
golang.org/x/crypto v0.19.0 // indirect
224225
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect
225226
golang.org/x/mod v0.15.0 // indirect
226-
golang.org/x/oauth2 v0.17.0 // indirect
227-
golang.org/x/sys v0.18.0 // indirect
228-
golang.org/x/term v0.18.0 // indirect
227+
golang.org/x/oauth2 v0.16.0 // indirect
228+
golang.org/x/sys v0.17.0 // indirect
229+
golang.org/x/term v0.17.0 // indirect
229230
golang.org/x/time v0.5.0 // indirect
230231
golang.org/x/tools v0.18.0 // indirect
231232
google.golang.org/api v0.162.0 // indirect
@@ -244,10 +245,11 @@ replace (
244245
// use cosmos keyring
245246
github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0
246247
github.com/cockroachdb/pebble => github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811
247-
github.com/cosmos/cosmos-sdk => github.com/mmsqe/cosmos-sdk v0.46.0-beta2.0.20240315010123-8531387f70f0
248+
github.com/cosmos/cosmos-sdk => github.com/yihuang/cosmos-sdk v0.43.0-beta1.0.20240317073920-e8d54831f9a9
248249
github.com/ethereum/go-ethereum => github.com/crypto-org-chain/go-ethereum v1.10.20-0.20231207063621-43cf32d91c3e
249250
// Fix upstream GHSA-h395-qcrw-5vmq vulnerability.
250251
// TODO Remove it: https://github.com/cosmos/cosmos-sdk/issues/10409
251252
github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.7.0
252253
github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
254+
github.com/tidwall/btree => github.com/yihuang/btree v0.0.0-20240215071918-6726a9b22e40
253255
)

0 commit comments

Comments
 (0)