8000 imp(staking): implement the EditValidator function for staking precompiled contract by luchenqun · Pull Request #2051 · evmos/evmos · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

imp(staking): implement the EditValidator function for staking precompiled contract #2051

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 43 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
2f0086e
imp(staking): implement the EditValidator function for staking precom…
luchenqun Nov 17, 2023
5af26cd
imp(staking): use [do-not-modify] instead of empty string for validat…
luchenqun Nov 17, 2023
baadf8b
chore: make lint
luchenqun Nov 17, 2023
e921cd4
imp(staking): update EditValidator
luchenqun Nov 21, 2023
8a6d9d4
imp(staking): change ValidatorAddress string to address type for Edit…
luchenqun Nov 21, 2023
ad64a4e
chore: merge origin/main
luchenqun Nov 22, 2023
f629146
imp(staking): use the opposite value for readability
luchenqun Nov 22, 2023
12a27e4
Merge remote-tracking branch 'luke/luke/edit-validator' into luke/edi…
luchenqun Nov 22, 2023
e984a85
imp(staking): add commissionRate and minSelfDelegation check for nega…
luchenqun Nov 22, 2023
5db4f00
imp(staking): import cosmossdk errors instead of cosmos-sdk errors
luchenqun Nov 22, 2023
3d14fc4
imp(staking): update commissionRate and minSelfDelegation check
luchenqun Nov 22, 2023
9054e13
imp(staking): update commissionRate check
luchenqun Nov 23, 2023
c1b61bb
chore: merge origin/main
luchenqun Nov 23, 2023
1624f51 8000
imp(staking): update commissionRate and minSelfDelegation check
luchenqun Nov 23, 2023
e04b596
chore: add comment
luchenqun Nov 28, 2023
0ab4188
chore: update debug info
luchenqun Feb 29, 2024
555cb9f
Merge branch 'main' into luke/edit-validator
Vvaradinov Mar 5, 2024
4c95b4b
Merge branch 'main' into luke/edit-validator
Vvaradinov Mar 5, 2024
4104a0f
fix: fix imports, events and types, format and lint
Vvaradinov Mar 5, 2024
f6ffb98
fix: solidity linter
Vvaradinov Mar 5, 2024
5e726a4
chore: update comment
luchenqun Mar 5, 2024
37dc750
chore: update comment
luchenqun Mar 5, 2024
4bd2a58
Merge branch 'main' into luke/edit-validator
Vvaradinov Mar 6, 2024
8731af1
Merge branch 'main' into luke/edit-validator
Vvaradinov Mar 6, 2024
3250475
Merge branch 'main' into luke/edit-validator
fedekunze May 13, 2024
f619666
add unit tests
GAtom22 May 13, 2024
51e7901
add unit tests for event editValidator
GAtom22 May 13, 2024
f500827
make format
GAtom22 May 13, 2024
7590db3
fix lint warnings
GAtom22 May 13, 2024
4a561c0
fix chlog
GAtom22 May 13, 2024
73e6fc9
add more test cases
GAtom22 May 13, 2024
aff12ac
make format
GAtom22 May 13, 2024
f2e8c23
address lint issues
GAtom22 May 13, 2024
fbecf54
chore: fix some comment
luchenqun May 14, 2024
45e3892
chore: fix some comment
luchenqun May 14, 2024
191c28b
chore: fix some comment
luchenqun May 14, 2024
a20b724
fix(test): fix a unit test for editValidator
luchenqun May 14, 2024
9c2a646
Merge branch 'main' into luke/edit-validator
0xstepit May 14, 2024
ac34985
Merge branch 'main' into luke/edit-validator
luchenqun May 15, 2024
b3cbafa
Merge branch 'main' into luke/edit-validator
luchenqun May 17, 2024
4844766
Merge branch 'main' into luke/edit-validator
luchenqun May 19, 2024
0698506
Merge branch 'main' into luke/edit-validator
luchenqun May 22, 2024
d25a4ec
Merge branch 'main' into luke/edit-validator
GAtom22 May 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.m 8000 d
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
- (precompiles) [#2529](https://github.com/evmos/evmos/pull/2529) Remove Outposts precompiles.
- (upgrade) [#2533](https://github.com/evmos/evmos/pull/2533) Add upgrade handler for v19.
- (precompiles) [#2550](https://github.com/evmos/evmos/pull/2550) Update secp256r1 curve precompile bech32 address to its corresponding value.
- (staking) [#2051](https://github.com/evmos/evmos/pull/2051) Implement the `EditValidator` function for staking precompiled contract.
- (evm) [#2373](https://github.com/evmos/evmos/pull/2373) Remove check on hardcoded ChainID identifier.

### Bug Fixes
Expand Down
2 changes: 1 addition & 1 deletion precompiles/common/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const (
ErrInvalidAmount = "invalid amount: %v"
// ErrInvalidDelegator is raised when the delegator address is not valid.
ErrInvalidDelegator = "invalid delegator address: %s"
// ErrInvalidValidator is raised when the Validator address is not valid.
// ErrInvalidValidator is raised when the validator address is not valid.
ErrInvalidValidator = "invalid validator address: %s"
// ErrInvalidDenom is raised when the denom is not valid.
ErrInvalidDenom = "invalid denom: %s"
Expand Down
41 changes: 36 additions & 5 deletions precompiles/staking/StakingI.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,18 @@ StakingI constant STAKING_CONTRACT = StakingI(STAKING_PRECOMPILE_ADDRESS);

/// @dev Define all the available staking methods.
string constant MSG_CREATE_VALIDATOR = "/cosmos.staking.v1beta1.MsgCreateValidator";
string constant MSG_EDIT_VALIDATOR = "/cosmos.staking.v1beta1.MsgEditValidator";
string constant MSG_DELEGATE = "/cosmos.staking.v1beta1.MsgDelegate";
string constant MSG_UNDELEGATE = "/cosmos.staking.v1beta1.MsgUndelegate";
string constant MSG_REDELEGATE = "/cosmos.staking.v1beta1.MsgBeginRedelegate";
string constant MSG_CANCEL_UNDELEGATION = "/cosmos.staking.v1beta1.MsgCancelUnbondingDelegation";

/// @dev Constant used in flags to indicate that commission rate field should not be updated
int256 constant DO_NOT_MODIFY_COMMISSION_RATE = -1;

/// @dev Constant used in flags to indicate that min self delegation field should not be updated
int256 constant DO_NOT_MODIFY_MIN_SELF_DELEGATION = -1;

/// @dev Defines the initial description to be used for creating
/// a validator.
struct Description {
Expand All @@ -41,7 +48,6 @@ struct Commission {
uint256 updateTime;
}


/// @dev Represents a validator in the staking module.
struct Validator {
string operatorAddress;
Expand Down Expand Up @@ -142,6 +148,21 @@ interface StakingI is authorization.AuthorizationI {
uint256 value
) external returns (bool success);

/// @dev Defines a method for edit a validator.
/// @param description Description parameter to be updated. Use the string "[do-not-modify]"
/// as the value of fields that should not be updated.
/// @param commissionRate CommissionRate parameter to be updated.
/// Use commissionRate = -1 to keep the current value and not update it.
/// @param minSelfDelegation MinSelfDelegation parameter to be updated.
/// Use minSelfDelegation = -1 to keep the current value and not update it.
/// @return success Whether or not edit validator was successful.
function editValidator(
Description calldata description,
address validatorAddress,
int256 commissionRate,
int256 minSelfDelegation
) external returns (bool success);

/// @dev Defines a method for performing a delegation of coins from a delegator to a validator.
/// @param delegatorAddress The address of the delegator
/// @param validatorAddress The address of the validator
Expand Down Expand Up @@ -210,7 +231,10 @@ interface StakingI is authorization.AuthorizationI {
function unbondingDelegation(
address delegatorAddress,
string memory validatorAddress
) external view returns (UnbondingDelegationOutput calldata unbondingDelegation);
)
external
view
returns (UnbondingDelegationOutput calldata unbondingDelegation);

/// @dev Queries validator info for a given validator address.
/// @param validatorAddress The address of the validator.
Expand All @@ -237,7 +261,7 @@ interface StakingI is authorization.AuthorizationI {
/// @param delegatorAddress The address of the delegator.
/// @param srcValidatorAddress Defines the validator address to redelegate from.
/// @param dstValidatorAddress Defines the validator address to redelegate to.
/// @return redelegation The active redelegations for the given delegator, source and destination
/// @return redelegation The active redelegations for the given delegator, source and destination
/// validator combination.
function redelegation(
address delegatorAddress,
Expand Down Expand Up @@ -270,9 +294,16 @@ interface StakingI is authorization.AuthorizationI {
/// @dev CreateValidator defines an Event emitted when a create a new validator.
/// @param validatorAddress The address of the validator
/// @param value The amount of coin being self delegated
event CreateValidator(
event CreateValidator(address indexed validatorAddress, uint256 value);

/// @dev EditValidator defines an Event emitted when edit a validator.
/// @param validatorAddress The address of the validator.
/// @param commissionRate The commission rate.
/// @param minSelfDelegation The min self delegation.
event EditValidator(
address indexed validatorAddress,
uint256 value
int256 commissionRate,
int256 minSelfDelegation
);

/// @dev Delegate defines an Event emitted when a given amount of tokens are delegated from the
Expand Down
86 changes: 86 additions & 0 deletions precompiles/staking/abi.json
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,31 @@
"name": "Delegate",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "validatorAddress",
"type": "address"
},
{
"indexed": false,
"internalType": "int256",
"name": "commissionRate",
"type": "int256"
},
{
"indexed": false,
"internalType": "int256",
"name": "minSelfDelegation",
"type": "int256"
}
],
"name": "EditValidator",
"type": "event"
},
{
"anonymous": false,
"inputs": [
Expand Down Expand Up @@ -514,6 +539,67 @@
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "string",
"name": "moniker",
"type": "string"
},
{
"internalType": "string",
"name": "identity",
"type": "string"
},
{
"internalType": "string",
"name": "website",
"type": "string"
},
{
"internalType": "string",
"name": "securityContact",
"type": "string"
},
{
"internalType": "string",
"name": "details",
"type": "string"
}
],
"internalType": "struct Description",
"name": "description",
"type": "tuple"
},
{
"internalType": "address",
"name": "validatorAddress",
"type": "address"
},
{
"internalType": "int256",
"name": "commissionRate",
"type": "int256"
},
{
"internalType": "int256",
"name": "minSelfDelegation",
"type": "int256"
}
],
"name": "editValidator",
"outputs": [
{
"internalType": "bool",
"name": "success",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
Expand Down
2 changes: 2 additions & 0 deletions precompiles/staking/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ const (
ErrDifferentOriginFromDelegator = "origin address %s is not the same as delegator address %s"
// ErrNoDelegationFound is raised when no delegation is found for the given delegator and validator addresses.
ErrNoDelegationFound = "delegation with delegator %s not found for validator %s"
// ErrDifferentOriginFromValidator is raised when the origin address is not the same as the validator address.
ErrDifferentOriginFromValidator = "origin address %s is not the same as validator operator address %s"
)
43 changes: 40 additions & 3 deletions precompiles/staking/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (
const (
// EventTypeCreateValidator defines the event type for the staking CreateValidator transaction.
EventTypeCreateValidator = "CreateValidator"
// EventTypeEditValidator defines the event type for the staking EditValidator transaction.
EventTypeEditValidator = "EditValidator"
// EventTypeDelegate defines the event type for the staking Delegate transaction.
EventTypeDelegate = "Delegate"
// EventTypeUnbond defines the event type for the staking Undelegate transaction.
Expand Down Expand Up @@ -129,7 +131,7 @@ func (p Precompile) EmitCreateValidatorEvent(ctx sdk.Context, stateDB vm.StateDB
// Prepare the event topics
event := p.ABI.Events[EventTypeCreateValidator]

topics, err := p.createValidatorTxTopics(2, event, validatorAddr)
topics, err := p.createEditValidatorTxTopics(2, event, validatorAddr)
if err != nil {
return err
}
Expand All @@ -148,6 +150,41 @@ func (p Precompile) EmitCreateValidatorEvent(ctx sdk.Context, stateDB vm.StateDB
return nil
}

// EmitEditValidatorEvent creates a new edit validator event emitted on a EditValidator transaction.
func (p Precompile) EmitEditValidatorEvent(ctx sdk.Context, stateDB vm.StateDB, msg *stakingtypes.MsgEditValidator, validatorAddr common.Address) error {
// Prepare the event topics
event := p.ABI.Events[EventTypeEditValidator]

topics, err := p.createEditValidatorTxTopics(2, event, validatorAddr)
if err != nil {
return err
}

commissionRate := big.NewInt(DoNotModifyCommissionRate)
if msg.CommissionRate != nil {
commissionRate = msg.CommissionRate.BigInt()
}

minSelfDelegation := big.NewInt(DoNotModifyMinSelfDelegation)
if msg.MinSelfDelegation != nil {
minSelfDelegation = msg.MinSelfDelegation.BigInt()
}

// Prepare the event data
var b bytes.Buffer
b.Write(cmn.PackNum(reflect.ValueOf(commissionRate)))
b.Write(cmn.PackNum(reflect.ValueOf(minSelfDelegation)))

stateDB.AddLog(&ethtypes.Log{
Address: p.Address(),
Topics: topics,
Data: b.Bytes(),
BlockNumber: uint64(ctx.BlockHeight()),
})

return nil
}

// EmitDelegateEvent creates a new delegate event emitted on a Delegate transaction.
func (p Precompile) EmitDelegateEvent(ctx sdk.Context, stateDB vm.StateDB, msg *stakingtypes.MsgDelegate, delegatorAddr common.Address) error {
valAddr, err := sdk.ValAddressFromBech32(msg.ValidatorAddress)
Expand Down Expand Up @@ -307,8 +344,8 @@ func (p Precompile) createStakingTxTopics(topicsLen uint64, event abi.Event, del
return topics, nil
}

// createValidatorTxTopics creates the topics for staking transaction CreateValidator.
func (p Precompile) createValidatorTxTopics(topicsLen uint64, event abi.Event, validatorAddr common.Address) ([]common.Hash, error) {
// createEditValidatorTxTopics creates the topics for staking transactions CreateValidator and EditValidator.
func (p Precompile) createEditValidatorTxTopics(topicsLen uint64, event abi.Event, validatorAddr common.Address) ([]common.Hash, error) {
topics := make([]common.Hash, topicsLen)
// NOTE: If your solidity event contains indexed event types, then they become a topic rather than part of the data property of the log.
// In solidity you may only have up to 4 topics but only 3 indexed event types. The first topic is always the signature of the event.
Expand Down
70 changes: 70 additions & 0 deletions precompiles/staking/events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,76 @@ func (s *PrecompileTestSuite) TestCreateValidatorEvent() {
}
}

func (s *PrecompileTestSuite) TestEditValidatorEvent() {
var (
valOperAddr common.Address
method = s.precompile.Methods[staking.EditValidatorMethod]
minSelfDel = big.NewInt(11)
commRate = math.LegacyNewDecWithPrec(5, 2).BigInt()
)
testCases := []struct {
name string
malleate func() []interface{}
expErr bool
errContains string
postCheck func()
}{
{
name: "success - the correct event is emitted",
malleate: func() []interface{} {
return []interface{}{
staking.Description{
Moniker: "node0-edited",
Identity: "",
Website: "",
SecurityContact: "",
Details: "",
},
valOperAddr,
commRate,
minSelfDel,
}
},
postCheck: func() {
s.Require().Equal(len(s.stateDB.Logs()), 1)
log := s.stateDB.Logs()[0]
s.Require().Equal(log.Address, s.precompile.Address())

// Check event signature matches the one emitted
event := s.precompile.ABI.Events[staking.EventTypeEditValidator]
s.Require().Equal(crypto.Keccak256Hash([]byte(event.Sig)), common.HexToHash(log.Topics[0].Hex()))
s.Require().Equal(log.BlockNumber, uint64(s.ctx.BlockHeight()))

// Check the fully unpacked event matches the one emitted
var editValidatorEvent staking.EventEditValidator
err := cmn.UnpackLog(s.precompile.ABI, &editValidatorEvent, staking.EventTypeEditValidator, *log)
s.Require().NoError(err)
s.Require().Equal(valOperAddr, editValidatorEvent.ValidatorAddress)
s.Require().Equal(minSelfDel, editValidatorEvent.MinSelfDelegation)
s.Require().Equal(commRate, editValidatorEvent.CommissionRate)
},
},
}

for _, tc := range testCases {
s.Run(tc.name, func() {
s.SetupTest() // reset
valOperAddr = common.BytesToAddress(s.validators[0].GetOperator().Bytes())

contract := vm.NewContract(vm.AccountRef(valOperAddr), s.precompile, big.NewInt(0), 200000)
_, err := s.precompile.EditValidator(s.ctx, valOperAddr, contract, s.stateDB, &method, tc.malleate())

if tc.expErr {
s.Require().Error(err)
s.Require().Contains(err.Error(), tc.errContains)
} else {
s.Require().NoError(err)
tc.postCheck()
}
})
}
}

func (s *PrecompileTestSuite) TestDelegateEvent() {
var (
delegationAmt = big.NewInt(1500000000000000000)
Expand Down
4 changes: 4 additions & 0 deletions precompiles/staking/staking.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ func (p Precompile) Run(evm *vm.EVM, contract *vm.Contract, readOnly bool) (bz [
// Staking transactions
case CreateValidatorMethod:
bz, err = p.CreateValidator(ctx, evm.Origin, contract, stateDB, method, args)
case EditValidatorMethod:
bz, err = p.EditValidator(ctx, evm.Origin, contract, stateDB, method, args)
case DelegateMethod:
bz, err = p.Delegate(ctx, evm.Origin, contract, stateDB, method, args)
case UndelegateMethod:
Expand Down Expand Up @@ -154,6 +156,7 @@ func (p Precompile) Run(evm *vm.EVM, contract *vm.Contract, readOnly bool) (bz [
//
// Available staking transactions are:
// - CreateValidator
// - EditValidator
// - Delegate
// - Undelegate
// - Redelegate
Expand All @@ -167,6 +170,7 @@ func (p Precompile) Run(evm *vm.EVM, contract *vm.Contract, readOnly bool) (bz [
func (Precompile) IsTransaction(method string) bool {
switch method {
case CreateValidatorMethod,
EditValidatorMethod,
DelegateMethod,
UndelegateMethod,
RedelegateMethod,
Expand Down
Loading
0