Skip to content

Commit ec1a928

Browse files
zsystmvladjdk
andauthored
feat: set no-op router to EvidenceKeeper for evmd (cosmos#271)
* add default router for evidence keeper * fix type handling When calling submitEvidence through hardhat(ethers.js), type conversion from args[1] into Equivocation doesn't work. * fix lint * enable evidence precompile at local_node.sh * implement no-op evidence handler * remove un-used code --------- Co-authored-by: Vlad J <[email protected]>
1 parent 16ec2d0 commit ec1a928

File tree

8 files changed

+63
-43
lines changed

8 files changed

+63
-43
lines changed

contracts/solidity/precompiles/evidence/IEvidence.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ interface IEvidence {
3333
/// @dev Submit evidence of misbehavior (equivocation)
3434
/// @param evidence The evidence of misbehavior
3535
/// @return success True if the evidence was submitted successfully
36-
function submitEvidence(Equivocation calldata evidence) external returns (bool success);
36+
function submitEvidence(address submitter, Equivocation calldata evidence) external returns (bool success);
3737

3838
/// @dev Query evidence by hash
3939
/// @param evidenceHash The hash of the evidence to query

evmd/app.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package evmd
22

33
import (
4+
"context"
45
"encoding/json"
56
"fmt"
67
"io"
@@ -30,7 +31,6 @@ import (
3031
feemarketkeeper "github.com/cosmos/evm/x/feemarket/keeper"
3132
feemarkettypes "github.com/cosmos/evm/x/feemarket/types"
3233
ibccallbackskeeper "github.com/cosmos/evm/x/ibc/callbacks/keeper"
33-
3434
// NOTE: override ICS20 keeper to support IBC transfers of ERC20 tokens
3535
"github.com/cosmos/evm/x/ibc/transfer"
3636
transferkeeper "github.com/cosmos/evm/x/ibc/transfer/keeper"
@@ -62,6 +62,7 @@ import (
6262
"cosmossdk.io/log"
6363
storetypes "cosmossdk.io/store/types"
6464
"cosmossdk.io/x/evidence"
65+
"cosmossdk.io/x/evidence/exported"
6566
evidencekeeper "cosmossdk.io/x/evidence/keeper"
6667
evidencetypes "cosmossdk.io/x/evidence/types"
6768
"cosmossdk.io/x/feegrant"
@@ -447,6 +448,13 @@ func NewExampleApp(
447448
app.AccountKeeper.AddressCodec(),
448449
runtime.ProvideCometInfoService(),
449450
)
451+
// Initialize a router for the evidence keeper.
452+
// This prevents nil panic when submitEvidence is called.
453+
// See precompiles/evidence/tx.go for more details.
454+
router := evidencetypes.NewRouter()
455+
router = router.AddRoute(evidencetypes.RouteEquivocation, noOpEquivocationHandler(evidenceKeeper))
456+
evidenceKeeper.SetRouter(router)
457+
450458
// If evidence needs to be handled for the app, set routes in router here and seal
451459
app.EvidenceKeeper = *evidenceKeeper
452460

@@ -1133,3 +1141,23 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino
11331141

11341142
return paramsKeeper
11351143
}
1144+
1145+
// testEquivocationHandler is a no-op equivocation handler for testing purposes.
1146+
// You should not use this in production code, as it does not handle equivocation properly.
1147+
func noOpEquivocationHandler(_ interface{}) evidencetypes.Handler {
1148+
return func(_ context.Context, e exported.Evidence) error {
1149+
if err := e.ValidateBasic(); err != nil {
1150+
return err
1151+
}
1152+
1153+
ee, ok := e.(*evidencetypes.Equivocation)
1154+
if !ok {
1155+
return fmt.Errorf("unexpected evidence type: %T", e)
1156+
}
1157+
if ee.Height%2 == 0 {
1158+
return fmt.Errorf("unexpected even evidence height: %d", ee.Height)
1159+
}
1160+
1161+
return nil
1162+
}
1163+
}

local_node.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ if [[ $overwrite == "y" || $overwrite == "Y" ]]; then
136136
jq '.app_state["bank"]["denom_metadata"]=[{"description":"The native staking token for evmd.","denom_units":[{"denom":"atest","exponent":0,"aliases":["attotest"]},{"denom":"test","exponent":18,"aliases":[]}],"base":"atest","display":"test","name":"Test Token","symbol":"TEST","uri":"","uri_hash":""}]' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS"
137137

138138
# Enable precompiles in EVM params
139-
jq '.app_state["evm"]["params"]["active_static_precompiles"]=["0x0000000000000000000000000000000000000100","0x0000000000000000000000000000000000000400","0x0000000000000000000000000000000000000800","0x0000000000000000000000000000000000000801","0x0000000000000000000000000000000000000802","0x0000000000000000000000000000000000000803","0x0000000000000000000000000000000000000804","0x0000000000000000000000000000000000000805"]' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS"
139+
jq '.app_state["evm"]["params"]["active_static_precompiles"]=["0x0000000000000000000000000000000000000100","0x0000000000000000000000000000000000000400","0x0000000000000000000000000000000000000800","0x0000000000000000000000000000000000000801","0x0000000000000000000000000000000000000802","0x0000000000000000000000000000000000000803","0x0000000000000000000000000000000000000804","0x0000000000000000000000000000000000000805", "0x0000000000000000000000000000000000000806", "0x0000000000000000000000000000000000000807"]' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS"
140140

141141
# Set EVM config
142142
jq '.app_state["evm"]["params"]["evm_denom"]="atest"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS"

precompiles/evidence/IEvidence.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ interface IEvidence {
3333
/// @dev Submit evidence of misbehavior (equivocation)
3434
/// @param evidence The evidence of misbehavior
3535
/// @return success True if the evidence was submitted successfully
36-
function submitEvidence(Equivocation calldata evidence) external returns (bool success);
36+
function submitEvidence(address submitter, Equivocation calldata evidence) external returns (bool success);
3737

3838
/// @dev Query evidence by hash
3939
/// @param evidenceHash The hash of the evidence to query

precompiles/evidence/abi.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,11 @@
150150
},
151151
{
152152
"inputs": [
153+
{
154+
"internalType": "address",
155+
"name": "submitter",
156+
"type": "address"
157+
},
153158
{
154159
"components": [
155160
{

precompiles/evidence/tx.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,19 @@ func (p Precompile) SubmitEvidence(
2121
method *abi.Method,
2222
args []interface{},
2323
) ([]byte, error) {
24-
msg, submitterHexAddr, err := NewMsgSubmitEvidence(args)
24+
msg, submitterHexAddr, err := NewMsgSubmitEvidence(method, args)
2525
if err != nil {
2626
return nil, err
2727
}
2828

29+
handler, err := p.evidenceKeeper.GetEvidenceHandler(msg.GetEvidence().Route())
30+
if err != nil {
31+
return nil, fmt.Errorf("failed to get evidence handler: %w", err)
32+
}
33+
if handler == nil {
34+
return nil, fmt.Errorf("no evidence handler found for route: %s", msg.GetEvidence().Route())
35+
}
36+
2937
msgSender := contract.Caller()
3038
if msgSender != submitterHexAddr {
3139
return nil, fmt.Errorf(cmn.ErrRequesterIsNotMsgSender, msgSender.String(), submitterHexAddr.String())

precompiles/evidence/types.go

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ import (
44
"fmt"
55
"time"
66

7+
"github.com/ethereum/go-ethereum/accounts/abi"
78
"github.com/ethereum/go-ethereum/common"
89

910
cmn "github.com/cosmos/evm/precompiles/common"
1011

1112
evidencetypes "cosmossdk.io/x/evidence/types"
1213

13-
sdk "github.com/cosmos/cosmos-sdk/types"
1414
"github.com/cosmos/cosmos-sdk/types/query"
1515
)
1616

@@ -59,8 +59,12 @@ func (e EquivocationData) ToEquivocation() *evidencetypes.Equivocation {
5959
}
6060
}
6161

62+
type SubmitEquivocationInput struct {
63+
Equivocation EquivocationData
64+
}
65+
6266
// NewMsgSubmitEvidence creates a new MsgSubmitEvidence instance.
63-
func NewMsgSubmitEvidence(args []interface{}) (*evidencetypes.MsgSubmitEvidence, common.Address, error) {
67+
func NewMsgSubmitEvidence(method *abi.Method, args []interface{}) (*evidencetypes.MsgSubmitEvidence, common.Address, error) {
6468
emptyAddr := common.Address{}
6569
if len(args) != 2 {
6670
return nil, emptyAddr, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 2, len(args))
@@ -71,18 +75,21 @@ func NewMsgSubmitEvidence(args []interface{}) (*evidencetypes.MsgSubmitEvidence,
7175
return nil, emptyAddr, fmt.Errorf("invalid submitter address")
7276
}
7377

74-
equivocation, ok := args[1].(EquivocationData)
75-
if !ok {
76-
return nil, emptyAddr, fmt.Errorf("invalid equivocation evidence")
78+
inputs := method.Inputs[1:] // Skip the first input which is the submitter address
79+
args = args[1:]
80+
var input SubmitEquivocationInput
81+
if err := inputs.Copy(&input, args); err != nil {
82+
return nil, emptyAddr, fmt.Errorf("failed to copy inputs: %w", err)
7783
}
7884

79-
// Convert the EquivocationData to a types.Equivocation
80-
evidence := equivocation.ToEquivocation()
85+
equivocation := input.Equivocation.ToEquivocation()
86+
if equivocation == nil {
87+
return nil, emptyAddr, fmt.Errorf("invalid equivocation evidence")
88+
}
8189

82-
// Create the MsgSubmitEvidence using the SDK msg builder
8390
msg, err := evidencetypes.NewMsgSubmitEvidence(
84-
sdk.AccAddress(submitterAddress.Bytes()),
85-
evidence,
91+
submitterAddress.Bytes(),
92+
equivocation,
8693
)
8794
if err != nil {
8895
return nil, emptyAddr, fmt.Errorf("failed to create evidence message: %w", err)
Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
11
package evidence
22

33
import (
4-
"context"
5-
"fmt"
6-
74
"github.com/stretchr/testify/suite"
85

96
"github.com/cosmos/evm/precompiles/evidence"
107
"github.com/cosmos/evm/testutil/integration/evm/factory"
118
"github.com/cosmos/evm/testutil/integration/evm/grpc"
129
"github.com/cosmos/evm/testutil/integration/evm/network"
1310
testkeyring "github.com/cosmos/evm/testutil/keyring"
14-
15-
"cosmossdk.io/x/evidence/exported"
16-
"cosmossdk.io/x/evidence/types"
1711
)
1812

1913
type PrecompileTestSuite struct {
@@ -45,10 +39,6 @@ func (s *PrecompileTestSuite) SetupTest() {
4539
grpcHandler := grpc.NewIntegrationHandler(nw)
4640
txFactory := factory.New(nw, grpcHandler)
4741

48-
router := types.NewRouter()
49-
router = router.AddRoute(types.RouteEquivocation, testEquivocationHandler(nw.App.GetEvidenceKeeper()))
50-
nw.App.GetEvidenceKeeper().SetRouter(router)
51-
5242
s.network = nw
5343
s.factory = txFactory
5444
s.grpcHandler = grpcHandler
@@ -60,21 +50,3 @@ func (s *PrecompileTestSuite) SetupTest() {
6050
panic(err)
6151
}
6252
}
63-
64-
func testEquivocationHandler(_ interface{}) types.Handler {
65-
return func(_ context.Context, e exported.Evidence) error {
66-
if err := e.ValidateBasic(); err != nil {
67-
return err
68-
}
69-
70-
ee, ok := e.(*types.Equivocation)
71-
if !ok {
72-
return fmt.Errorf("unexpected evidence type: %T", e)
73-
}
74-
if ee.Height%2 == 0 {
75-
return fmt.Errorf("unexpected even evidence height: %d", ee.Height)
76-
}
77-
78-
return nil
79-
}
80-
}

0 commit comments

Comments
 (0)