feat: distribution precompile

This commit is contained in:
MiniFrenchBread 2025-03-07 20:02:32 +08:00
parent f2bd26e111
commit 9f16644d2b
7 changed files with 164 additions and 200 deletions

View File

@ -1,29 +1,4 @@
[ [
{
"inputs": [],
"name": "CommunityPool",
"outputs": [
{
"components": [
{
"internalType": "string",
"name": "denom",
"type": "string"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"internalType": "struct DecCoin[]",
"name": "pool",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
@ -158,30 +133,6 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "address",
"name": "depositor",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "fundCommunityPool",
"outputs": [
{
"internalType": "bool",
"name": "success",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "params", "name": "params",
@ -219,11 +170,6 @@
}, },
{ {
"inputs": [ "inputs": [
{
"internalType": "address",
"name": "delegatorAddress",
"type": "address"
},
{ {
"internalType": "address", "internalType": "address",
"name": "withdrawerAddress", "name": "withdrawerAddress",
@ -455,11 +401,6 @@
}, },
{ {
"inputs": [ "inputs": [
{
"internalType": "address",
"name": "delegatorAddress",
"type": "address"
},
{ {
"internalType": "string", "internalType": "string",
"name": "validatorAddress", "name": "validatorAddress",
@ -490,13 +431,7 @@
"type": "function" "type": "function"
}, },
{ {
"inputs": [ "inputs": [],
{
"internalType": "address",
"name": "validatorAddress",
"type": "address"
}
],
"name": "withdrawValidatorCommission", "name": "withdrawValidatorCommission",
"outputs": [ "outputs": [
{ {

File diff suppressed because one or more lines are too long

View File

@ -18,7 +18,6 @@ const (
DistributionFunctionSetWithdrawAddress = "setWithdrawAddress" DistributionFunctionSetWithdrawAddress = "setWithdrawAddress"
DistributionFunctionWithdrawDelegatorRewards = "withdrawDelegatorRewards" DistributionFunctionWithdrawDelegatorRewards = "withdrawDelegatorRewards"
DistributionFunctionWithdrawValidatorCommission = "withdrawValidatorCommission" DistributionFunctionWithdrawValidatorCommission = "withdrawValidatorCommission"
DistributionFunctionFundCommunityPool = "fundCommunityPool"
// query // query
DistributionFunctionParams = "params" DistributionFunctionParams = "params"
DistributionFunctionValidatorDistributionInfo = "validatorDistributionInfo" DistributionFunctionValidatorDistributionInfo = "validatorDistributionInfo"
@ -29,7 +28,6 @@ const (
DistributionFunctionDelegationTotalRewards = "delegationTotalRewards" DistributionFunctionDelegationTotalRewards = "delegationTotalRewards"
DistributionFunctionDelegatorValidators = "delegatorValidators" DistributionFunctionDelegatorValidators = "delegatorValidators"
DistributionFunctionDelegatorWithdrawAddress = "delegatorWithdrawAddress" DistributionFunctionDelegatorWithdrawAddress = "delegatorWithdrawAddress"
DistributionFunctionCommunityPool = "CommunityPool"
) )
var _ vm.PrecompiledContract = &DistributionPrecompile{} var _ vm.PrecompiledContract = &DistributionPrecompile{}
@ -69,8 +67,7 @@ func (d *DistributionPrecompile) IsTx(method string) bool {
switch method { switch method {
case DistributionFunctionSetWithdrawAddress, case DistributionFunctionSetWithdrawAddress,
DistributionFunctionWithdrawDelegatorRewards, DistributionFunctionWithdrawDelegatorRewards,
DistributionFunctionWithdrawValidatorCommission, DistributionFunctionWithdrawValidatorCommission:
DistributionFunctionFundCommunityPool:
return true return true
default: default:
return false return false
@ -109,17 +106,13 @@ func (d *DistributionPrecompile) Run(evm *vm.EVM, contract *vm.Contract, readonl
bz, err = d.DelegatorValidators(ctx, evm, method, args) bz, err = d.DelegatorValidators(ctx, evm, method, args)
case DistributionFunctionDelegatorWithdrawAddress: case DistributionFunctionDelegatorWithdrawAddress:
bz, err = d.DelegatorWithdrawAddress(ctx, evm, method, args) bz, err = d.DelegatorWithdrawAddress(ctx, evm, method, args)
case DistributionFunctionCommunityPool:
bz, err = d.CommunityPool(ctx, evm, method, args)
// txs // txs
case DistributionFunctionSetWithdrawAddress: case DistributionFunctionSetWithdrawAddress:
bz, err = d.CreateValidator(ctx, evm, stateDB, contract, method, args) bz, err = d.SetWithdrawAddress(ctx, evm, stateDB, contract, method, args)
case DistributionFunctionWithdrawDelegatorRewards: case DistributionFunctionWithdrawDelegatorRewards:
bz, err = d.EditValidator(ctx, evm, stateDB, contract, method, args) bz, err = d.WithdrawDelegatorReward(ctx, evm, stateDB, contract, method, args)
case DistributionFunctionWithdrawValidatorCommission: case DistributionFunctionWithdrawValidatorCommission:
bz, err = d.Delegate(ctx, evm, stateDB, contract, method, args) bz, err = d.WithdrawValidatorCommission(ctx, evm, stateDB, contract, method, args)
case DistributionFunctionFundCommunityPool:
bz, err = d.BeginRedelegate(ctx, evm, stateDB, contract, method, args)
} }
if err != nil { if err != nil {

View File

@ -156,17 +156,3 @@ func (d *DistributionPrecompile) DelegatorWithdrawAddress(ctx sdk.Context, _ *vm
return method.Outputs.Pack(withdrawAddress) return method.Outputs.Pack(withdrawAddress)
} }
func (d *DistributionPrecompile) CommunityPool(ctx sdk.Context, _ *vm.EVM, method *abi.Method, args []interface{}) ([]byte, error) {
req, err := NewQueryCommunityPoolRequest(args)
if err != nil {
return nil, err
}
response, err := distributionkeeper.Querier{Keeper: d.distributionKeeper}.CommunityPool(ctx, req)
if err != nil {
return nil, err
}
return method.Outputs.Pack(convertCommunityPoolResponse(response))
}

View File

@ -0,0 +1,76 @@
package distribution
import (
sdk "github.com/cosmos/cosmos-sdk/types"
distributionkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/evmos/ethermint/x/evm/statedb"
)
func (d *DistributionPrecompile) SetWithdrawAddress(
ctx sdk.Context,
evm *vm.EVM,
stateDB *statedb.StateDB,
contract *vm.Contract,
method *abi.Method,
args []interface{},
) ([]byte, error) {
msg, err := NewMsgSetWithdrawAddress(args, contract.CallerAddress)
if err != nil {
return nil, err
}
// validation
// execute
_, err = distributionkeeper.NewMsgServerImpl(d.distributionKeeper).SetWithdrawAddress(ctx, msg)
if err != nil {
return nil, err
}
// emit events
return method.Outputs.Pack()
}
func (d *DistributionPrecompile) WithdrawDelegatorReward(
ctx sdk.Context,
evm *vm.EVM,
stateDB *statedb.StateDB,
contract *vm.Contract,
method *abi.Method,
args []interface{},
) ([]byte, error) {
msg, err := NewMsgWithdrawDelegatorReward(args, contract.CallerAddress)
if err != nil {
return nil, err
}
// validation
// execute
_, err = distributionkeeper.NewMsgServerImpl(d.distributionKeeper).WithdrawDelegatorReward(ctx, msg)
if err != nil {
return nil, err
}
// emit events
return method.Outputs.Pack()
}
func (d *DistributionPrecompile) WithdrawValidatorCommission(
ctx sdk.Context,
evm *vm.EVM,
stateDB *statedb.StateDB,
contract *vm.Contract,
method *abi.Method,
args []interface{},
) ([]byte, error) {
msg, err := NewMsgWithdrawValidatorCommission(args, contract.CallerAddress)
if err != nil {
return nil, err
}
// validation
// execute
_, err = distributionkeeper.NewMsgServerImpl(d.distributionKeeper).WithdrawValidatorCommission(ctx, msg)
if err != nil {
return nil, err
}
// emit events
return method.Outputs.Pack()
}

View File

@ -303,3 +303,42 @@ func NewQueryCommunityPoolRequest(args []interface{}) (*distributiontypes.QueryC
func convertCommunityPoolResponse(response *distributiontypes.QueryCommunityPoolResponse) []DecCoin { func convertCommunityPoolResponse(response *distributiontypes.QueryCommunityPoolResponse) []DecCoin {
return convertDecCoins(response.Pool) return convertDecCoins(response.Pool)
} }
func NewMsgSetWithdrawAddress(args []interface{}, sender common.Address) (*distributiontypes.MsgSetWithdrawAddress, error) {
if len(args) != 1 {
return nil, fmt.Errorf(precompiles_common.ErrInvalidNumberOfArgs, 1, len(args))
}
withdrawAddress := args[0].(common.Address)
msg := &distributiontypes.MsgSetWithdrawAddress{
DelegatorAddress: sdk.AccAddress(sender.Bytes()).String(),
WithdrawAddress: sdk.AccAddress(withdrawAddress.Bytes()).String(),
}
return msg, msg.ValidateBasic()
}
func NewMsgWithdrawDelegatorReward(args []interface{}, sender common.Address) (*distributiontypes.MsgWithdrawDelegatorReward, error) {
if len(args) != 1 {
return nil, fmt.Errorf(precompiles_common.ErrInvalidNumberOfArgs, 1, len(args))
}
validatorAddress := args[0].(common.Address)
msg := &distributiontypes.MsgWithdrawDelegatorReward{
DelegatorAddress: sdk.AccAddress(sender.Bytes()).String(),
ValidatorAddress: sdk.AccAddress(validatorAddress.Bytes()).String(),
}
return msg, msg.ValidateBasic()
}
func NewMsgWithdrawValidatorCommission(args []interface{}, sender common.Address) (*distributiontypes.MsgWithdrawValidatorCommission, error) {
if len(args) != 0 {
return nil, fmt.Errorf(precompiles_common.ErrInvalidNumberOfArgs, 0, len(args))
}
msg := &distributiontypes.MsgWithdrawValidatorCommission{
ValidatorAddress: sdk.AccAddress(sender.Bytes()).String(),
}
return msg, msg.ValidateBasic()
}

View File

@ -33,38 +33,31 @@ interface IDistribution {
/** /**
* @dev SetWithdrawAddress defines a method to change the withdraw address for a delegator (or validator self-delegation). * @dev SetWithdrawAddress defines a method to change the withdraw address for a delegator (or validator self-delegation).
* delegator address is msg.sener.
*
* cosmos grpc: rpc SetWithdrawAddress(MsgSetWithdrawAddress) returns (MsgSetWithdrawAddressResponse); * cosmos grpc: rpc SetWithdrawAddress(MsgSetWithdrawAddress) returns (MsgSetWithdrawAddressResponse);
*/ */
function setWithdrawAddress( function setWithdrawAddress(
address delegatorAddress,
address withdrawerAddress address withdrawerAddress
) external returns (bool success); ) external returns (bool success);
/** /**
* @dev WithdrawDelegatorReward defines a method to withdraw rewards of delegator from a single validator. * @dev WithdrawDelegatorReward defines a method to withdraw rewards of delegator from a single validator.
* delegator address is msg.sender.
*
* cosmos grpc: rpc WithdrawDelegatorReward(MsgWithdrawDelegatorReward) returns (MsgWithdrawDelegatorRewardResponse); * cosmos grpc: rpc WithdrawDelegatorReward(MsgWithdrawDelegatorReward) returns (MsgWithdrawDelegatorRewardResponse);
*/ */
function withdrawDelegatorRewards( function withdrawDelegatorRewards(
address delegatorAddress,
string memory validatorAddress string memory validatorAddress
) external returns (Coin[] calldata amount); ) external returns (Coin[] calldata amount);
/** /**
* @dev WithdrawValidatorCommission defines a method to withdraw the full commission to the validator address. * @dev WithdrawValidatorCommission defines a method to withdraw the full commission to the validator address.
* validator address is msg.sender.
*
* cosmos grpc: rpc WithdrawValidatorCommission(MsgWithdrawValidatorCommission) returns (MsgWithdrawValidatorCommissionResponse); * cosmos grpc: rpc WithdrawValidatorCommission(MsgWithdrawValidatorCommission) returns (MsgWithdrawValidatorCommissionResponse);
*/ */
function withdrawValidatorCommission( function withdrawValidatorCommission() external returns (Coin[] calldata amount);
address validatorAddress
) external returns (Coin[] calldata amount);
/**
* @dev FundCommunityPool defines a method to allow an account to directly fund the community pool.
* cosmos grpc: rpc FundCommunityPool(MsgFundCommunityPool) returns (MsgFundCommunityPoolResponse);
*/
function fundCommunityPool(
address depositor,
uint256 amount
) external returns (bool success);
/*=== cosmos query ===*/ /*=== cosmos query ===*/
@ -156,10 +149,4 @@ interface IDistribution {
function delegatorWithdrawAddress( function delegatorWithdrawAddress(
address delegatorAddress address delegatorAddress
) external view returns (address withdrawAddress); ) external view returns (address withdrawAddress);
/**
* @dev CommunityPool queries the community pool coins.
* cosmos grpc: rpc CommunityPool(QueryCommunityPoolRequest) returns (QueryCommunityPoolResponse);
*/
function CommunityPool() external view returns (DecCoin[] memory pool);
} }