Skip to content

Commit ebcaefa

Browse files
fix: use address codecs in precompiles (cosmos#291)
* address codec * ok * update all the other ones * add tests * tests and stuff and lint * use common.Address * make it so these can be defined by the end user * comment explainer * private * linter
1 parent 8d21baf commit ebcaefa

File tree

26 files changed

+1946
-84
lines changed

26 files changed

+1946
-84
lines changed

evmd/precompiles.go

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"fmt"
55
"maps"
66

7+
addresscodec "github.com/cosmos/cosmos-sdk/codec/address"
8+
sdk "github.com/cosmos/cosmos-sdk/types"
79
"github.com/ethereum/go-ethereum/common"
810
"github.com/ethereum/go-ethereum/core/vm"
911

@@ -22,6 +24,7 @@ import (
2224
evmkeeper "github.com/cosmos/evm/x/vm/keeper"
2325
channelkeeper "github.com/cosmos/ibc-go/v10/modules/core/04-channel/keeper"
2426

27+
"cosmossdk.io/core/address"
2528
evidencekeeper "cosmossdk.io/x/evidence/keeper"
2629

2730
"github.com/cosmos/cosmos-sdk/codec"
@@ -31,6 +34,43 @@ import (
3134
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
3235
)
3336

37+
// Optionals define some optional params that can be applied to _some_ precompiles.
38+
// Extend this struct, add a sane default to defaultOptionals, and an Option function to provide users with a non-breaking
39+
// way to provide custom args to certain precompiles.
40+
type Optionals struct {
41+
AddressCodec address.Codec // used by gov/staking
42+
ValidatorAddrCodec address.Codec // used by slashing
43+
ConsensusAddrCodec address.Codec // used by slashing
44+
}
45+
46+
func defaultOptionals() Optionals {
47+
return Optionals{
48+
AddressCodec: addresscodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()),
49+
ValidatorAddrCodec: addresscodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()),
50+
ConsensusAddrCodec: addresscodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()),
51+
}
52+
}
53+
54+
type Option func(opts *Optionals)
55+
56+
func WithAddressCodec(codec address.Codec) Option {
57+
return func(opts *Optionals) {
58+
opts.AddressCodec = codec
59+
}
60+
}
61+
62+
func WithValidatorAddrCodec(codec address.Codec) Option {
63+
return func(opts *Optionals) {
64+
opts.ValidatorAddrCodec = codec
65+
}
66+
}
67+
68+
func WithConsensusAddrCodec(codec address.Codec) Option {
69+
return func(opts *Optionals) {
70+
opts.ConsensusAddrCodec = codec
71+
}
72+
}
73+
3474
const bech32PrecompileBaseGas = 6_000
3575

3676
// NewAvailableStaticPrecompiles returns the list of all available static precompiled contracts from Cosmos EVM.
@@ -48,7 +88,12 @@ func NewAvailableStaticPrecompiles(
4888
slashingKeeper slashingkeeper.Keeper,
4989
evidenceKeeper evidencekeeper.Keeper,
5090
codec codec.Codec,
91+
opts ...Option,
5192
) map[common.Address]vm.PrecompiledContract {
93+
options := defaultOptionals()
94+
for _, opt := range opts {
95+
opt(&options)
96+
}
5297
// Clone the mapping from the latest EVM fork.
5398
precompiles := maps.Clone(vm.PrecompiledContractsBerlin)
5499

@@ -60,7 +105,7 @@ func NewAvailableStaticPrecompiles(
60105
panic(fmt.Errorf("failed to instantiate bech32 precompile: %w", err))
61106
}
62107

63-
stakingPrecompile, err := stakingprecompile.NewPrecompile(stakingKeeper)
108+
stakingPrecompile, err := stakingprecompile.NewPrecompile(stakingKeeper, options.AddressCodec)
64109
if err != nil {
65110
panic(fmt.Errorf("failed to instantiate staking precompile: %w", err))
66111
}
@@ -69,6 +114,7 @@ func NewAvailableStaticPrecompiles(
69114
distributionKeeper,
70115
stakingKeeper,
71116
evmKeeper,
117+
options.AddressCodec,
72118
)
73119
if err != nil {
74120
panic(fmt.Errorf("failed to instantiate distribution precompile: %w", err))
@@ -90,12 +136,12 @@ func NewAvailableStaticPrecompiles(
90136
panic(fmt.Errorf("failed to instantiate bank precompile: %w", err))
91137
}
92138

93-
govPrecompile, err := govprecompile.NewPrecompile(govKeeper, codec)
139+
govPrecompile, err := govprecompile.NewPrecompile(govKeeper, codec, options.AddressCodec)
94140
if err != nil {
95141
panic(fmt.Errorf("failed to instantiate gov precompile: %w", err))
96142
}
97143

98-
slashingPrecompile, err := slashingprecompile.NewPrecompile(slashingKeeper)
144+
slashingPrecompile, err := slashingprecompile.NewPrecompile(slashingKeeper, options.ValidatorAddrCodec, options.ConsensusAddrCodec)
99145
if err != nil {
100146
panic(fmt.Errorf("failed to instantiate slashing precompile: %w", err))
101147
}

precompiles/distribution/distribution.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
evmkeeper "github.com/cosmos/evm/x/vm/keeper"
1414
evmtypes "github.com/cosmos/evm/x/vm/types"
1515

16+
"cosmossdk.io/core/address"
1617
storetypes "cosmossdk.io/store/types"
1718

1819
distributionkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
@@ -32,6 +33,7 @@ type Precompile struct {
3233
distributionKeeper distributionkeeper.Keeper
3334
stakingKeeper stakingkeeper.Keeper
3435
evmKeeper *evmkeeper.Keeper
36+
addrCdc address.Codec
3537
}
3638

3739
// NewPrecompile creates a new distribution Precompile instance as a
@@ -40,6 +42,7 @@ func NewPrecompile(
4042
distributionKeeper distributionkeeper.Keeper,
4143
stakingKeeper stakingkeeper.Keeper,
4244
evmKeeper *evmkeeper.Keeper,
45+
addrCdc address.Codec,
4346
) (*Precompile, error) {
4447
newAbi, err := cmn.LoadABI(f, "abi.json")
4548
if err != nil {
@@ -55,6 +58,7 @@ func NewPrecompile(
5558
stakingKeeper: stakingKeeper,
5659
distributionKeeper: distributionKeeper,
5760
evmKeeper: evmKeeper,
61+
addrCdc: addrCdc,
5862
}
5963

6064
// SetAddress defines the address of the distribution compile contract.

precompiles/distribution/query.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ func (p Precompile) DelegationRewards(
139139
method *abi.Method,
140140
args []interface{},
141141
) ([]byte, error) {
142-
req, err := NewDelegationRewardsRequest(args)
142+
req, err := NewDelegationRewardsRequest(args, p.addrCdc)
143143
if err != nil {
144144
return nil, err
145145
}
@@ -160,7 +160,7 @@ func (p Precompile) DelegationTotalRewards(
160160
method *abi.Method,
161161
args []interface{},
162162
) ([]byte, error) {
163-
req, err := NewDelegationTotalRewardsRequest(args)
163+
req, err := NewDelegationTotalRewardsRequest(args, p.addrCdc)
164164
if err != nil {
165165
return nil, err
166166
}
@@ -184,7 +184,7 @@ func (p Precompile) DelegatorValidators(
184184
method *abi.Method,
185185
args []interface{},
186186
) ([]byte, error) {
187-
req, err := NewDelegatorValidatorsRequest(args)
187+
req, err := NewDelegatorValidatorsRequest(args, p.addrCdc)
188188
if err != nil {
189189
return nil, err
190190
}
@@ -206,7 +206,7 @@ func (p Precompile) DelegatorWithdrawAddress(
206206
method *abi.Method,
207207
args []interface{},
208208
) ([]byte, error) {
209-
req, err := NewDelegatorWithdrawAddressRequest(args)
209+
req, err := NewDelegatorWithdrawAddressRequest(args, p.addrCdc)
210210
if err != nil {
211211
return nil, err
212212
}

precompiles/distribution/tx.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func (p Precompile) SetWithdrawAddress(
9393
method *abi.Method,
9494
args []interface{},
9595
) ([]byte, error) {
96-
msg, delegatorHexAddr, err := NewMsgSetWithdrawAddress(args)
96+
msg, delegatorHexAddr, err := NewMsgSetWithdrawAddress(args, p.addrCdc)
9797
if err != nil {
9898
return nil, err
9999
}
@@ -123,7 +123,7 @@ func (p *Precompile) WithdrawDelegatorReward(
123123
method *abi.Method,
124124
args []interface{},
125125
) ([]byte, error) {
126-
msg, delegatorHexAddr, err := NewMsgWithdrawDelegatorReward(args)
126+
msg, delegatorHexAddr, err := NewMsgWithdrawDelegatorReward(args, p.addrCdc)
127127
if err != nil {
128128
return nil, err
129129
}
@@ -185,7 +185,7 @@ func (p *Precompile) FundCommunityPool(
185185
method *abi.Method,
186186
args []interface{},
187187
) ([]byte, error) {
188-
msg, depositorHexAddr, err := NewMsgFundCommunityPool(args)
188+
msg, depositorHexAddr, err := NewMsgFundCommunityPool(args, p.addrCdc)
189189
if err != nil {
190190
return nil, err
191191
}
@@ -217,7 +217,7 @@ func (p *Precompile) DepositValidatorRewardsPool(
217217
method *abi.Method,
218218
args []interface{},
219219
) ([]byte, error) {
220-
msg, depositorHexAddr, err := NewMsgDepositValidatorRewardsPool(args)
220+
msg, depositorHexAddr, err := NewMsgDepositValidatorRewardsPool(args, p.addrCdc)
221221
if err != nil {
222222
return nil, err
223223
}

precompiles/distribution/types.go

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
cmn "github.com/cosmos/evm/precompiles/common"
1111
"github.com/cosmos/evm/utils"
1212

13+
"cosmossdk.io/core/address"
1314
"cosmossdk.io/math"
1415

1516
sdk "github.com/cosmos/cosmos-sdk/types"
@@ -77,7 +78,7 @@ func parseClaimRewardsArgs(args []interface{}) (common.Address, uint32, error) {
7778
}
7879

7980
// NewMsgSetWithdrawAddress creates a new MsgSetWithdrawAddress instance.
80-
func NewMsgSetWithdrawAddress(args []interface{}) (*distributiontypes.MsgSetWithdrawAddress, common.Address, error) {
81+
func NewMsgSetWithdrawAddress(args []interface{}, addrCdc address.Codec) (*distributiontypes.MsgSetWithdrawAddress, common.Address, error) {
8182
if len(args) != 2 {
8283
return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 2, len(args))
8384
}
@@ -98,16 +99,20 @@ func NewMsgSetWithdrawAddress(args []interface{}) (*distributiontypes.MsgSetWith
9899
}
99100
}
100101

102+
delAddr, err := addrCdc.BytesToString(delegatorAddress.Bytes())
103+
if err != nil {
104+
return nil, common.Address{}, fmt.Errorf("failed to decode delegator address: %w", err)
105+
}
101106
msg := &distributiontypes.MsgSetWithdrawAddress{
102-
DelegatorAddress: sdk.AccAddress(delegatorAddress.Bytes()).String(),
107+
DelegatorAddress: delAddr,
103108
WithdrawAddress: withdrawerAddress,
104109
}
105110

106111
return msg, delegatorAddress, nil
107112
}
108113

109114
// NewMsgWithdrawDelegatorReward creates a new MsgWithdrawDelegatorReward instance.
110-
func NewMsgWithdrawDelegatorReward(args []interface{}) (*distributiontypes.MsgWithdrawDelegatorReward, common.Address, error) {
115+
func NewMsgWithdrawDelegatorReward(args []interface{}, addrCdc address.Codec) (*distributiontypes.MsgWithdrawDelegatorReward, common.Address, error) {
111116
if len(args) != 2 {
112117
return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 2, len(args))
113118
}
@@ -119,8 +124,12 @@ func NewMsgWithdrawDelegatorReward(args []interface{}) (*distributiontypes.MsgWi
119124

120125
validatorAddress, _ := args[1].(string)
121126

127+
delAddr, err := addrCdc.BytesToString(delegatorAddress.Bytes())
128+
if err != nil {
129+
return nil, common.Address{}, fmt.Errorf("failed to decode delegator address: %w", err)
130+
}
122131
msg := &distributiontypes.MsgWithdrawDelegatorReward{
123-
DelegatorAddress: sdk.AccAddress(delegatorAddress.Bytes()).String(),
132+
DelegatorAddress: delAddr,
124133
ValidatorAddress: validatorAddress,
125134
}
126135

@@ -148,7 +157,7 @@ func NewMsgWithdrawValidatorCommission(args []interface{}) (*distributiontypes.M
148157
}
149158

150159
// NewMsgFundCommunityPool creates a new NewMsgFundCommunityPool message.
151-
func NewMsgFundCommunityPool(args []interface{}) (*distributiontypes.MsgFundCommunityPool, common.Address, error) {
160+
func NewMsgFundCommunityPool(args []interface{}, addrCdc address.Codec) (*distributiontypes.MsgFundCommunityPool, common.Address, error) {
152161
emptyAddr := common.Address{}
153162
if len(args) != 2 {
154163
return nil, emptyAddr, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 2, len(args))
@@ -169,16 +178,20 @@ func NewMsgFundCommunityPool(args []interface{}) (*distributiontypes.MsgFundComm
169178
return nil, emptyAddr, fmt.Errorf(ErrInvalidAmount, "amount arg")
170179
}
171180

181+
depAddr, err := addrCdc.BytesToString(depositorAddress.Bytes())
182+
if err != nil {
183+
return nil, common.Address{}, fmt.Errorf("failed to decode depositor address: %w", err)
184+
}
172185
msg := &distributiontypes.MsgFundCommunityPool{
173-
Depositor: sdk.AccAddress(depositorAddress.Bytes()).String(),
186+
Depositor: depAddr,
174187
Amount: amt,
175188
}
176189

177190
return msg, depositorAddress, nil
178191
}
179192

180193
// NewMsgDepositValidatorRewardsPool creates a new MsgDepositValidatorRewardsPool message.
181-
func NewMsgDepositValidatorRewardsPool(args []interface{}) (*distributiontypes.MsgDepositValidatorRewardsPool, common.Address, error) {
194+
func NewMsgDepositValidatorRewardsPool(args []interface{}, addrCdc address.Codec) (*distributiontypes.MsgDepositValidatorRewardsPool, common.Address, error) {
182195
if len(args) != 3 {
183196
return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 3, len(args))
184197
}
@@ -200,8 +213,13 @@ func NewMsgDepositValidatorRewardsPool(args []interface{}) (*distributiontypes.M
200213
return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidAmount, err.Error())
201214
}
202215

216+
depAddr, err := addrCdc.BytesToString(depositorAddress.Bytes())
217+
if err != nil {
218+
return nil, common.Address{}, fmt.Errorf("failed to decode depositor address: %w", err)
219+
}
220+
203221
msg := &distributiontypes.MsgDepositValidatorRewardsPool{
204-
Depositor: sdk.AccAddress(depositorAddress.Bytes()).String(),
222+
Depositor: depAddr,
205223
ValidatorAddress: validatorAddress,
206224
Amount: amount,
207225
}
@@ -280,7 +298,7 @@ func NewValidatorSlashesRequest(method *abi.Method, args []interface{}) (*distri
280298

281299
// NewDelegationRewardsRequest creates a new QueryDelegationRewardsRequest instance and does sanity
282300
// checks on the provided arguments.
283-
func NewDelegationRewardsRequest(args []interface{}) (*distributiontypes.QueryDelegationRewardsRequest, error) {
301+
func NewDelegationRewardsRequest(args []interface{}, addrCdc address.Codec) (*distributiontypes.QueryDelegationRewardsRequest, error) {
284302
if len(args) != 2 {
285303
return nil, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 2, len(args))
286304
}
@@ -292,15 +310,19 @@ func NewDelegationRewardsRequest(args []interface{}) (*distributiontypes.QueryDe
292310

293311
validatorAddress, _ := args[1].(string)
294312

313+
delAddr, err := addrCdc.BytesToString(delegatorAddress.Bytes())
314+
if err != nil {
315+
return nil, fmt.Errorf("failed to decode delegator address: %w", err)
316+
}
295317
return &distributiontypes.QueryDelegationRewardsRequest{
296-
DelegatorAddress: sdk.AccAddress(delegatorAddress.Bytes()).String(),
318+
DelegatorAddress: delAddr,
297319
ValidatorAddress: validatorAddress,
298320
}, nil
299321
}
300322

301323
// NewDelegationTotalRewardsRequest creates a new QueryDelegationTotalRewardsRequest instance and does sanity
302324
// checks on the provided arguments.
303-
func NewDelegationTotalRewardsRequest(args []interface{}) (*distributiontypes.QueryDelegationTotalRewardsRequest, error) {
325+
func NewDelegationTotalRewardsRequest(args []interface{}, addrCdc address.Codec) (*distributiontypes.QueryDelegationTotalRewardsRequest, error) {
304326
if len(args) != 1 {
305327
return nil, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 1, len(args))
306328
}
@@ -310,14 +332,18 @@ func NewDelegationTotalRewardsRequest(args []interface{}) (*distributiontypes.Qu
310332
return nil, fmt.Errorf(cmn.ErrInvalidDelegator, args[0])
311333
}
312334

335+
delAddr, err := addrCdc.BytesToString(delegatorAddress.Bytes())
336+
if err != nil {
337+
return nil, fmt.Errorf("failed to decode delegator address: %w", err)
338+
}
313339
return &distributiontypes.QueryDelegationTotalRewardsRequest{
314-
DelegatorAddress: sdk.AccAddress(delegatorAddress.Bytes()).String(),
340+
DelegatorAddress: delAddr,
315341
}, nil
316342
}
317343

318344
// NewDelegatorValidatorsRequest creates a new QueryDelegatorValidatorsRequest instance and does sanity
319345
// checks on the provided arguments.
320-
func NewDelegatorValidatorsRequest(args []interface{}) (*distributiontypes.QueryDelegatorValidatorsRequest, error) {
346+
func NewDelegatorValidatorsRequest(args []interface{}, addrCdc address.Codec) (*distributiontypes.QueryDelegatorValidatorsRequest, error) {
321347
if len(args) != 1 {
322348
return nil, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 1, len(args))
323349
}
@@ -327,14 +353,18 @@ func NewDelegatorValidatorsRequest(args []interface{}) (*distributiontypes.Query
327353
return nil, fmt.Errorf(cmn.ErrInvalidDelegator, args[0])
328354
}
329355

356+
delAddr, err := addrCdc.BytesToString(delegatorAddress.Bytes())
357+
if err != nil {
358+
return nil, fmt.Errorf("failed to decode delegator address: %w", err)
359+
}
330360
return &distributiontypes.QueryDelegatorValidatorsRequest{
331-
DelegatorAddress: sdk.AccAddress(delegatorAddress.Bytes()).String(),
361+
DelegatorAddress: delAddr,
332362
}, nil
333363
}
334364

335365
// NewDelegatorWithdrawAddressRequest creates a new QueryDelegatorWithdrawAddressRequest instance and does sanity
336366
// checks on the provided arguments.
337-
func NewDelegatorWithdrawAddressRequest(args []interface{}) (*distributiontypes.QueryDelegatorWithdrawAddressRequest, error) {
367+
func NewDelegatorWithdrawAddressRequest(args []interface{}, addrCdc address.Codec) (*distributiontypes.QueryDelegatorWithdrawAddressRequest, error) {
338368
if len(args) != 1 {
339369
return nil, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 1, len(args))
340370
}
@@ -344,8 +374,12 @@ func NewDelegatorWithdrawAddressRequest(args []interface{}) (*distributiontypes.
344374
return nil, fmt.Errorf(cmn.ErrInvalidDelegator, args[0])
345375
}
346376

377+
delAddr, err := addrCdc.BytesToString(delegatorAddress.Bytes())
378+
if err != nil {
379+
return nil, fmt.Errorf("failed to decode delegator address: %w", err)
380+
}
347381
return &distributiontypes.QueryDelegatorWithdrawAddressRequest{
348-
DelegatorAddress: sdk.AccAddress(delegatorAddress.Bytes()).String(),
382+
DelegatorAddress: delAddr,
349383
}, nil
350384
}
351385

0 commit comments

Comments
 (0)