Skip to content

Commit 8bc85f8

Browse files
committed
complete simapp
1 parent f54cf93 commit 8bc85f8

37 files changed

+5270
-23
lines changed

evmd/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
scripts/node-data

evmd/Dockerfile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
FROM golang:1.25-alpine AS builder
2+
3+
RUN apk add --no-cache curl build-base git bash file linux-headers eudev-dev
4+
5+
WORKDIR /src
6+
7+
COPY go.mod go.sum ./
8+
RUN go mod download
9+
10+
COPY . .
11+
RUN LEDGER_ENABLED=false make build
12+
13+
FROM alpine:3.21
14+
COPY --from=builder /src/build/evmd /bin/evmd
15+
ENTRYPOINT ["evmd"]

evmd/Makefile

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
2+
COMMIT := $(shell git log -1 --format='%H')
3+
APPNAME := evm
4+
BUILDDIR ?= $(CURDIR)/build
5+
DOCKER := $(shell which docker)
6+
7+
# don't override user values
8+
ifeq (,$(VERSION))
9+
VERSION := $(shell git describe --exact-match 2>/dev/null)
10+
# if VERSION is empty, then populate it with branch's name and raw commit hash
11+
ifeq (,$(VERSION))
12+
VERSION := $(BRANCH)-$(COMMIT)
13+
endif
14+
endif
15+
16+
help: ## List Commands
17+
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
18+
19+
.PHONY: help
20+
21+
check-all: ## Convenience to make sure everything is all good
22+
# @$(MAKE) proto-all # Uncomment if we add custom modules
23+
@$(MAKE) build
24+
@$(MAKE) test-unit
25+
@$(MAKE) lint
26+
@$(MAKE) e2e-contracts
27+
@$(MAKE) test-e2e
28+
29+
.PHONY: all
30+
31+
################################################################################
32+
## Build ##
33+
################################################################################
34+
35+
# forces Go to use its pure Go implementation of the DNS resolver
36+
build_tags = netgo
37+
build_tags += $(BUILD_TAGS)
38+
build_tags := $(strip $(build_tags))
39+
40+
whitespace :=
41+
empty = $(whitespace) $(whitespace)
42+
comma := ,
43+
build_tags_comma_sep := $(subst $(empty),$(comma),$(build_tags))
44+
45+
# process linker flags
46+
47+
# TODO: Figure out if '-s -w' is still needed
48+
# flags '-s -w' resolves an issue with xcode 16 and signing of go binaries
49+
# ref: https://github.com/golang/go/issues/63997
50+
ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=$(APPNAME) \
51+
-X github.com/cosmos/cosmos-sdk/version.AppName=$(APPNAME) \
52+
-X github.com/cosmos/cosmos-sdk/version.Version=$(VERSION) \
53+
-X github.com/cosmos/cosmos-sdk/version.Commit=$(COMMIT) \
54+
-X "github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags_comma_sep)" \
55+
-s -w
56+
57+
ifeq ($(LINK_STATICALLY),true)
58+
ldflags += -linkmode=external -extldflags "-Wl,-z,muldefs -static"
59+
endif
60+
ldflags += $(LDFLAGS)
61+
ldflags := $(strip $(ldflags))
62+
63+
BUILD_FLAGS := -tags "$(build_tags_comma_sep)" -ldflags '$(ldflags)' -trimpath
64+
65+
clean: ## Clean build artifacts
66+
rm -rf $(BUILDDIR)/ artifacts/
67+
68+
build: go.sum ## Build chain binary
69+
@echo "Building chain binary"
70+
go build -mod=readonly $(BUILD_FLAGS) -o $(BUILDDIR)/evmd ./cmd/evmd
71+
72+
73+
74+
.PHONY: build clean
75+
76+
################################################################################
77+
## Test ##
78+
################################################################################
79+
80+
test-unit: ## Run unit tests
81+
@echo Running unit tests...
82+
@go test -mod=readonly -v -timeout 30m ./...
83+
84+
test-race: ## Run unit tests with race condition reporting
85+
@echo Running unit tests with race condition reporting...
86+
@go test -mod=readonly -v -race -timeout 30m ./...
87+
88+
test-e2e: ## Run e2e tests
89+
@echo Running e2e tests...
90+
@cd e2e && go test -parallel 8 -mod=readonly -v -count=1 -timeout 30m .
91+
92+
.PHONY: test-unit test-race
93+
94+
################################################################################
95+
## Install ##
96+
################################################################################
97+
98+
install: ## Install dependencies
99+
@echo "--> ensure dependencies have not been modified"
100+
@go mod verify
101+
@echo "--> installing $(APPNAME)d"
102+
@go install $(BUILD_FLAGS) -mod=readonly ./cmd/$(APPNAME)d
103+
104+
.PHONY: install
105+
106+
################################################################################
107+
## Protobuf ##
108+
################################################################################
109+
110+
protoVer=0.17.1
111+
protoImageName=ghcr.io/cosmos/proto-builder:$(protoVer)
112+
protoImage=$(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace $(protoImageName)
113+
114+
proto-all: proto-format proto-lint proto-gen ## Generate Protobuf files
115+
116+
proto-gen: ## Generate Protobuf files
117+
@echo "Generating Protobuf files"
118+
@$(protoImage) sh ./scripts/protocgen.sh
119+
@go mod tidy
120+
121+
proto-format: ## Format Protobuf files
122+
@echo "Formatting Protobuf files"
123+
@$(protoImage) find ./ -name "*.proto" -exec clang-format -i {} \;
124+
125+
proto-lint: ## Lint Protobuf files
126+
@$(protoImage) buf lint --error-format=json
127+
128+
.PHONY: proto-all proto-gen proto-format proto-lint
129+
130+
################################################################################
131+
## Linting ##
132+
################################################################################
133+
134+
golangci_lint_cmd=golangci-lint
135+
136+
lint: ## Run linter
137+
@echo "--> Running linter"
138+
@$(golangci_lint_cmd) run ./... --timeout 15m -c .golangci.yml
139+
@cd e2e && $(golangci_lint_cmd) run ./... --timeout 15m -c ../.golangci.yml
140+
141+
lint-fix: ## Run linter and fix issues
142+
@echo "--> Running linter and fixing issues"
143+
@$(golangci_lint_cmd) run ./... --fix --timeout 15m -c .golangci.yml
144+
@cd e2e && $(golangci_lint_cmd) run ./... --fix --timeout 15m -c ../.golangci.yml
145+
146+
.PHONY: lint lint-fix
147+
148+
################################################################################
149+
## E2E Contract Artifacts ##
150+
################################################################################
151+
152+
SOLC_IMAGE ?= ethereum/solc:0.8.28
153+
E2E_CONTRACTS_DIR ?= e2e/contracts
154+
155+
e2e-contracts: ## Regenerate e2e embedded contract artifacts (ABI/BIN)
156+
@echo "--> Regenerating e2e contract artifacts with $(SOLC_IMAGE)"
157+
@docker run --rm -v $(CURDIR)/$(E2E_CONTRACTS_DIR):/contracts $(SOLC_IMAGE) --abi --bin -o /contracts --overwrite /contracts/Counter.sol /contracts/Reverter.sol
158+
159+
.PHONY: e2e-contracts

evmd/app/app.go

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,18 @@ import (
7474
"github.com/cosmos/cosmos-sdk/x/consensus"
7575
consensuskeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
7676
consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types"
77+
"github.com/cosmos/cosmos-sdk/x/distribution"
78+
distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
79+
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
7780
"github.com/cosmos/cosmos-sdk/x/genutil"
7881
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
7982
"github.com/cosmos/cosmos-sdk/x/gov"
8083
govclient "github.com/cosmos/cosmos-sdk/x/gov/client"
8184
govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
8285
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
86+
"github.com/cosmos/cosmos-sdk/x/slashing"
87+
slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
88+
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
8389
"github.com/cosmos/cosmos-sdk/x/staking"
8490
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
8591
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
@@ -101,6 +107,7 @@ var (
101107
// module account permissions
102108
maccPerms = map[string][]string{
103109
authtypes.FeeCollectorName: nil,
110+
distrtypes.ModuleName: nil,
104111
stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking},
105112
stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking},
106113
govtypes.ModuleName: {authtypes.Burner},
@@ -139,6 +146,8 @@ type App struct {
139146
AccountKeeper authkeeper.AccountKeeper
140147
BankKeeper bankkeeper.Keeper
141148
StakingKeeper *stakingkeeper.Keeper
149+
SlashingKeeper slashingkeeper.Keeper
150+
DistributionKeeper distrkeeper.Keeper
142151
GovKeeper govkeeper.Keeper
143152
IBCKeeper *ibckeeper.Keeper
144153
UpgradeKeeper *upgradekeeper.Keeper
@@ -186,8 +195,8 @@ func New(
186195

187196
keys := storetypes.NewKVStoreKeys(
188197
authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey,
189-
govtypes.StoreKey, upgradetypes.StoreKey, consensustypes.StoreKey,
190-
ibcexported.StoreKey,
198+
distrtypes.StoreKey, slashingtypes.StoreKey, govtypes.StoreKey,
199+
upgradetypes.StoreKey, consensustypes.StoreKey, ibcexported.StoreKey,
191200
// Cosmos EVM store keys
192201
evmtypes.StoreKey, feemarkettypes.StoreKey,
193202
)
@@ -258,6 +267,16 @@ func New(
258267
appCodec, runtime.NewKVStoreService(keys[stakingtypes.StoreKey]), app.AccountKeeper, app.BankKeeper, authAddr, address.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()), address.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()),
259268
)
260269

270+
app.DistributionKeeper = distrkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[distrtypes.StoreKey]), app.AccountKeeper, app.BankKeeper, app.StakingKeeper, authtypes.FeeCollectorName, authAddr)
271+
272+
app.SlashingKeeper = slashingkeeper.NewKeeper(appCodec, app.LegacyAmino(), runtime.NewKVStoreService(keys[slashingtypes.StoreKey]), app.StakingKeeper, authAddr)
273+
274+
// register the staking hooks
275+
// NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks
276+
app.StakingKeeper.SetHooks(
277+
stakingtypes.NewMultiStakingHooks(app.DistributionKeeper.Hooks(), app.SlashingKeeper.Hooks()),
278+
)
279+
261280
// get skipUpgradeHeights from the app options
262281
skipUpgradeHeights := map[int64]bool{}
263282
for _, h := range cast.ToIntSlice(appOpts.Get(server.FlagUnsafeSkipUpgrades)) {
@@ -278,12 +297,12 @@ func New(
278297
*/
279298
govKeeper := govkeeper.NewKeeper(
280299
appCodec, runtime.NewKVStoreService(keys[govtypes.StoreKey]), app.AccountKeeper, app.BankKeeper,
281-
app.StakingKeeper, dummyDistrKeeper{}, app.MsgServiceRouter(), govConfig, authAddr,
300+
app.StakingKeeper, app.DistributionKeeper, app.MsgServiceRouter(), govConfig, authAddr,
282301
)
283302

284303
app.GovKeeper = *govKeeper.SetHooks(
285304
govtypes.NewMultiGovHooks(
286-
// register the governance hooks
305+
// register the governance hooks
287306
),
288307
)
289308

@@ -312,6 +331,7 @@ func New(
312331
).WithStaticPrecompiles(
313332
StaticPrecompiles(
314333
*app.StakingKeeper,
334+
app.DistributionKeeper,
315335
app.BankKeeper,
316336
app.GovKeeper,
317337
app.IBCKeeper.ClientKeeper,
@@ -341,6 +361,8 @@ func New(
341361
auth.NewAppModule(appCodec, app.AccountKeeper, nil, nil),
342362
bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper, nil),
343363
gov.NewAppModule(appCodec, &app.GovKeeper, app.AccountKeeper, app.BankKeeper, nil),
364+
slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, nil, app.interfaceRegistry),
365+
distribution.NewAppModule(appCodec, app.DistributionKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, nil),
344366
staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, nil),
345367
upgrade.NewAppModule(app.UpgradeKeeper, app.AccountKeeper.AddressCodec()),
346368
consensus.NewAppModule(appCodec, app.ConsensusParamsKeeper),
@@ -378,6 +400,8 @@ func New(
378400
// NOTE: staking module is required if HistoricalEntries param > 0
379401
app.ModuleManager.SetOrderBeginBlockers(
380402
// Cosmos EVM BeginBlockers
403+
distrtypes.ModuleName,
404+
slashingtypes.ModuleName,
381405
stakingtypes.ModuleName,
382406
genutiltypes.ModuleName,
383407
ibcexported.ModuleName,
@@ -393,6 +417,8 @@ func New(
393417
banktypes.ModuleName,
394418
govtypes.ModuleName,
395419
stakingtypes.ModuleName,
420+
distrtypes.ModuleName,
421+
slashingtypes.ModuleName,
396422
authtypes.ModuleName,
397423
ibcexported.ModuleName,
398424

@@ -411,7 +437,9 @@ func New(
411437
genesisModuleOrder := []string{
412438
authtypes.ModuleName,
413439
banktypes.ModuleName,
440+
distrtypes.ModuleName,
414441
stakingtypes.ModuleName,
442+
slashingtypes.ModuleName,
415443
govtypes.ModuleName,
416444
ibcexported.ModuleName,
417445

@@ -461,10 +489,7 @@ func New(
461489
app.SetEndBlocker(app.EndBlocker)
462490
app.setAnteHandler(app.txConfig, maxGasWanted)
463491

464-
err = app.configureEVMMempool(appOpts, logger)
465-
if err != nil {
466-
panic(err)
467-
}
492+
app.configureEVMMempool(appOpts, logger)
468493

469494
// In v0.46, the SDK introduces _postHandlers_. PostHandlers are like
470495
// antehandlers, but are run _after_ the `runMsgs` execution. They are also

evmd/app/precompiles.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package app
22

33
import (
44
"fmt"
5+
distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
6+
distributionprecompile "github.com/cosmos/evm/precompiles/distribution"
57
"maps"
68

79
evmibcutils "github.com/cosmos/evm/ibc"
@@ -35,6 +37,7 @@ const (
3537
// NOTE: this should only be used during initialization of the Keeper.
3638
func StaticPrecompiles(
3739
stakingKeeper stakingkeeper.Keeper,
40+
distributionKeeper distrkeeper.Keeper,
3841
bankKeeper cmn.BankKeeper,
3942
govKeeper govkeeper.Keeper,
4043
clientKeeper evmibcutils.ClientKeeper,
@@ -66,6 +69,16 @@ func StaticPrecompiles(
6669
)
6770
precompiles[stakingPrecompile.Address()] = stakingPrecompile
6871

72+
distributionPrecompile := distributionprecompile.NewPrecompile(
73+
distributionKeeper,
74+
distrkeeper.NewMsgServerImpl(distributionKeeper),
75+
distrkeeper.NewQuerier(distributionKeeper),
76+
stakingKeeper,
77+
bankKeeper,
78+
addrCodec,
79+
)
80+
precompiles[distributionPrecompile.Address()] = distributionPrecompile
81+
6982
govPrecompile := govprecompile.NewPrecompile(
7083
govkeeper.NewMsgServerImpl(&govKeeper),
7184
govkeeper.NewQueryServer(&govKeeper),

evmd/e2e/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
`TODO: Add more information here`
2+
3+
## Keep containers running after tests
4+
5+
If you'd like to keep the docker containers running after the tests complete use the `KEEP_CONTAINERS` environment variable:
6+
7+
```
8+
KEEP_CONTAINERS=true make test-e2e
9+
```
10+
11+
Note that you should manually delete the created containers and networks before running the tests again.

evmd/e2e/contracts/Counter.abi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"},{"indexed":true,"internalType":"address","name":"caller","type":"address"}],"name":"ValueChanged","type":"event"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"value","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

evmd/e2e/contracts/Counter.bin

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
6080604052348015600e575f5ffd5b5061018e8061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610034575f3560e01c80633fa4f2451461003857806360fe47b114610056575b5f5ffd5b610040610072565b60405161004d91906100e6565b60405180910390f35b610070600480360381019061006b919061012d565b610077565b005b5f5481565b805f819055503373ffffffffffffffffffffffffffffffffffffffff167fc53a6612a7428e1fc89cb87169d69d64eaefe94f5b45d43f80f1ad9d7065d2c8826040516100c391906100e6565b60405180910390a250565b5f819050919050565b6100e0816100ce565b82525050565b5f6020820190506100f95f8301846100d7565b92915050565b5f5ffd5b61010c816100ce565b8114610116575f5ffd5b50565b5f8135905061012781610103565b92915050565b5f60208284031215610142576101416100ff565b5b5f61014f84828501610119565b9150509291505056fea2646970667358221220ed1c27ba6ebef7288fd90bf84d73c72414f497954e2e86599ca6234076aa963664736f6c634300081c0033

evmd/e2e/contracts/Counter.sol

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.20;
3+
4+
contract Counter {
5+
event ValueChanged(uint256 newValue, address indexed caller);
6+
7+
uint256 public value;
8+
9+
function set(uint256 newValue) external {
10+
value = newValue;
11+
emit ValueChanged(newValue, msg.sender);
12+
}
13+
}

evmd/e2e/contracts/Reverter.abi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"inputs":[{"internalType":"string","name":"reason","type":"string"}],"name":"revertWithReason","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"v","type":"uint256"},{"internalType":"uint256","name":"iters","type":"uint256"}],"name":"setThenBurnGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"x","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

0 commit comments

Comments
 (0)