mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-24 23:35:19 +00:00
feat: staking precompile
This commit is contained in:
parent
c80874b0ea
commit
e308e44dd6
5
.gitignore
vendored
5
.gitignore
vendored
@ -49,3 +49,8 @@ go.work.sum
|
||||
|
||||
# runtime
|
||||
run
|
||||
|
||||
# contracts
|
||||
precompiles/interfaces/build
|
||||
precompiles/interfaces/node_modules
|
||||
precompiles/interfaces/abis
|
@ -3,4 +3,5 @@ package common
|
||||
const (
|
||||
ErrGetStateDB = "get EVM StateDB failed"
|
||||
ErrInvalidNumberOfArgs = "invalid number of arguments; expected %d; got: %d"
|
||||
ErrSenderNotOrigin = "msg.sender is not from tx origin"
|
||||
)
|
||||
|
18
precompiles/common/utils.go
Normal file
18
precompiles/common/utils.go
Normal file
@ -0,0 +1,18 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"strings"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
||||
func ToLowerHexWithoutPrefix(addr common.Address) string {
|
||||
return strings.ToLower(addr.Hex()[2:])
|
||||
}
|
||||
|
||||
// BigIntToLegacyDec converts a uint number (18 decimals) to math.LegacyDec (18 decimals)
|
||||
func BigIntToLegacyDec(x *big.Int) math.LegacyDec {
|
||||
return math.LegacyNewDecFromBigIntWithPrec(x, math.LegacyPrecision)
|
||||
}
|
@ -139,11 +139,11 @@ func (d *DASignersPrecompile) Run(evm *vm.EVM, contract *vm.Contract, readonly b
|
||||
bz, err = d.RegisteredEpoch(ctx, evm, method, args)
|
||||
// txs
|
||||
case DASignersFunctionRegisterSigner:
|
||||
bz, err = d.RegisterSigner(ctx, evm, stateDB, method, args)
|
||||
bz, err = d.RegisterSigner(ctx, evm, stateDB, contract, method, args)
|
||||
case DASignersFunctionRegisterNextEpoch:
|
||||
bz, err = d.RegisterNextEpoch(ctx, evm, stateDB, method, args)
|
||||
bz, err = d.RegisterNextEpoch(ctx, evm, stateDB, contract, method, args)
|
||||
case DASignersFunctionUpdateSocket:
|
||||
bz, err = d.UpdateSocket(ctx, evm, stateDB, method, args)
|
||||
bz, err = d.UpdateSocket(ctx, evm, stateDB, contract, method, args)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
@ -62,7 +62,7 @@ func (d *DASignersPrecompile) IsSigner(ctx sdk.Context, _ *vm.EVM, method *abi.M
|
||||
if len(args) != 1 {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrInvalidNumberOfArgs, 1, len(args))
|
||||
}
|
||||
account := ToLowerHexWithoutPrefix(args[0].(common.Address))
|
||||
account := precopmiles_common.ToLowerHexWithoutPrefix(args[0].(common.Address))
|
||||
_, found, err := d.dasignersKeeper.GetSigner(ctx, account)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -74,7 +74,7 @@ func (d *DASignersPrecompile) RegisteredEpoch(ctx sdk.Context, _ *vm.EVM, method
|
||||
if len(args) != 2 {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrInvalidNumberOfArgs, 2, len(args))
|
||||
}
|
||||
account := ToLowerHexWithoutPrefix(args[0].(common.Address))
|
||||
account := precopmiles_common.ToLowerHexWithoutPrefix(args[0].(common.Address))
|
||||
epoch := args[1].(*big.Int).Uint64()
|
||||
_, found, err := d.dasignersKeeper.GetRegistration(ctx, epoch, account)
|
||||
if err != nil {
|
||||
|
@ -7,18 +7,30 @@ import (
|
||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/evmos/ethermint/x/evm/statedb"
|
||||
|
||||
precopmiles_common "github.com/0glabs/0g-chain/precompiles/common"
|
||||
)
|
||||
|
||||
func (d *DASignersPrecompile) RegisterSigner(ctx sdk.Context, evm *vm.EVM, stateDB *statedb.StateDB, method *abi.Method, args []interface{}) ([]byte, error) {
|
||||
func (d *DASignersPrecompile) RegisterSigner(
|
||||
ctx sdk.Context,
|
||||
evm *vm.EVM,
|
||||
stateDB *statedb.StateDB,
|
||||
contract *vm.Contract,
|
||||
method *abi.Method,
|
||||
args []interface{},
|
||||
) ([]byte, error) {
|
||||
msg, err := NewMsgRegisterSigner(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// validation
|
||||
sender := ToLowerHexWithoutPrefix(evm.Origin)
|
||||
sender := precopmiles_common.ToLowerHexWithoutPrefix(evm.Origin)
|
||||
if sender != msg.Signer.Account {
|
||||
return nil, fmt.Errorf(ErrInvalidSender, sender, msg.Signer.Account)
|
||||
}
|
||||
if contract.CallerAddress != evm.Origin {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrSenderNotOrigin)
|
||||
}
|
||||
// execute
|
||||
_, err = d.dasignersKeeper.RegisterSigner(sdk.WrapSDKContext(ctx), msg)
|
||||
if err != nil {
|
||||
@ -32,11 +44,22 @@ func (d *DASignersPrecompile) RegisterSigner(ctx sdk.Context, evm *vm.EVM, state
|
||||
return method.Outputs.Pack()
|
||||
}
|
||||
|
||||
func (d *DASignersPrecompile) RegisterNextEpoch(ctx sdk.Context, evm *vm.EVM, stateDB *statedb.StateDB, method *abi.Method, args []interface{}) ([]byte, error) {
|
||||
msg, err := NewMsgRegisterNextEpoch(args, ToLowerHexWithoutPrefix(evm.Origin))
|
||||
func (d *DASignersPrecompile) RegisterNextEpoch(
|
||||
ctx sdk.Context,
|
||||
evm *vm.EVM,
|
||||
stateDB *statedb.StateDB,
|
||||
contract *vm.Contract,
|
||||
method *abi.Method,
|
||||
args []interface{},
|
||||
) ([]byte, error) {
|
||||
msg, err := NewMsgRegisterNextEpoch(args, precopmiles_common.ToLowerHexWithoutPrefix(evm.Origin))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// validation
|
||||
if contract.CallerAddress != evm.Origin {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrSenderNotOrigin)
|
||||
}
|
||||
// execute
|
||||
_, err = d.dasignersKeeper.RegisterNextEpoch(sdk.WrapSDKContext(ctx), msg)
|
||||
if err != nil {
|
||||
@ -45,11 +68,22 @@ func (d *DASignersPrecompile) RegisterNextEpoch(ctx sdk.Context, evm *vm.EVM, st
|
||||
return method.Outputs.Pack()
|
||||
}
|
||||
|
||||
func (d *DASignersPrecompile) UpdateSocket(ctx sdk.Context, evm *vm.EVM, stateDB *statedb.StateDB, method *abi.Method, args []interface{}) ([]byte, error) {
|
||||
msg, err := NewMsgUpdateSocket(args, ToLowerHexWithoutPrefix(evm.Origin))
|
||||
func (d *DASignersPrecompile) UpdateSocket(
|
||||
ctx sdk.Context,
|
||||
evm *vm.EVM,
|
||||
stateDB *statedb.StateDB,
|
||||
contract *vm.Contract,
|
||||
method *abi.Method,
|
||||
args []interface{},
|
||||
) ([]byte, error) {
|
||||
msg, err := NewMsgUpdateSocket(args, precopmiles_common.ToLowerHexWithoutPrefix(evm.Origin))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// validation
|
||||
if contract.CallerAddress != evm.Origin {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrSenderNotOrigin)
|
||||
}
|
||||
// execute
|
||||
_, err = d.dasignersKeeper.UpdateSocket(sdk.WrapSDKContext(ctx), msg)
|
||||
if err != nil {
|
||||
|
@ -3,7 +3,6 @@ package dasigners
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"strings"
|
||||
|
||||
precopmiles_common "github.com/0glabs/0g-chain/precompiles/common"
|
||||
dasignerstypes "github.com/0glabs/0g-chain/x/dasigners/v1/types"
|
||||
@ -90,7 +89,7 @@ func NewQuerySignerRequest(args []interface{}) (*dasignerstypes.QuerySignerReque
|
||||
Accounts: make([]string, len(accounts)),
|
||||
}
|
||||
for i, account := range accounts {
|
||||
req.Accounts[i] = ToLowerHexWithoutPrefix(account)
|
||||
req.Accounts[i] = precopmiles_common.ToLowerHexWithoutPrefix(account)
|
||||
}
|
||||
return &req, nil
|
||||
}
|
||||
@ -139,10 +138,6 @@ func NewIDASignersSignerDetail(signer *dasignerstypes.Signer) IDASignersSignerDe
|
||||
}
|
||||
}
|
||||
|
||||
func ToLowerHexWithoutPrefix(addr common.Address) string {
|
||||
return strings.ToLower(addr.Hex()[2:])
|
||||
}
|
||||
|
||||
func NewMsgRegisterSigner(args []interface{}) (*dasignerstypes.MsgRegisterSigner, error) {
|
||||
if len(args) != 2 {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrInvalidNumberOfArgs, 2, len(args))
|
||||
@ -151,7 +146,7 @@ func NewMsgRegisterSigner(args []interface{}) (*dasignerstypes.MsgRegisterSigner
|
||||
signer := args[0].(IDASignersSignerDetail)
|
||||
return &dasignerstypes.MsgRegisterSigner{
|
||||
Signer: &dasignerstypes.Signer{
|
||||
Account: ToLowerHexWithoutPrefix(signer.Signer),
|
||||
Account: precopmiles_common.ToLowerHexWithoutPrefix(signer.Signer),
|
||||
Socket: signer.Socket,
|
||||
PubkeyG1: SerializeG1(signer.PkG1),
|
||||
PubkeyG2: SerializeG2(signer.PkG2),
|
||||
|
18
precompiles/interfaces/.solhint.json
Normal file
18
precompiles/interfaces/.solhint.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"extends": "solhint:recommended",
|
||||
"plugins": ["prettier"],
|
||||
"rules": {
|
||||
"avoid-low-level-calls": "off",
|
||||
"compiler-version": "off",
|
||||
"gas-custom-errors": "off",
|
||||
"explicit-types": ["warn", "implicit"],
|
||||
"func-visibility": ["warn", { "ignoreConstructors": true }],
|
||||
"max-states-count": "off",
|
||||
"no-empty-blocks": "off",
|
||||
"no-global-import": "off",
|
||||
"no-inline-assembly": "off",
|
||||
"not-rely-on-time": "off",
|
||||
"prettier/prettier": "error",
|
||||
"reason-string": "off"
|
||||
}
|
||||
}
|
88
precompiles/interfaces/contracts/IDASigners.sol
Normal file
88
precompiles/interfaces/contracts/IDASigners.sol
Normal file
@ -0,0 +1,88 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
pragma solidity >=0.8.0;
|
||||
|
||||
library BN254 {
|
||||
struct G1Point {
|
||||
uint X;
|
||||
uint Y;
|
||||
}
|
||||
|
||||
// Encoding of field elements is: X[1] * i + X[0]
|
||||
struct G2Point {
|
||||
uint[2] X;
|
||||
uint[2] Y;
|
||||
}
|
||||
}
|
||||
|
||||
interface IDASigners {
|
||||
/*=== struct ===*/
|
||||
struct SignerDetail {
|
||||
address signer;
|
||||
string socket;
|
||||
BN254.G1Point pkG1;
|
||||
BN254.G2Point pkG2;
|
||||
}
|
||||
|
||||
struct Params {
|
||||
uint tokensPerVote;
|
||||
uint maxVotesPerSigner;
|
||||
uint maxQuorums;
|
||||
uint epochBlocks;
|
||||
uint encodedSlices;
|
||||
}
|
||||
|
||||
/*=== event ===*/
|
||||
event NewSigner(
|
||||
address indexed signer,
|
||||
BN254.G1Point pkG1,
|
||||
BN254.G2Point pkG2
|
||||
);
|
||||
event SocketUpdated(address indexed signer, string socket);
|
||||
|
||||
/*=== function ===*/
|
||||
function params() external view returns (Params memory);
|
||||
|
||||
function epochNumber() external view returns (uint);
|
||||
|
||||
function quorumCount(uint _epoch) external view returns (uint);
|
||||
|
||||
function isSigner(address _account) external view returns (bool);
|
||||
|
||||
function getSigner(
|
||||
address[] memory _account
|
||||
) external view returns (SignerDetail[] memory);
|
||||
|
||||
function getQuorum(
|
||||
uint _epoch,
|
||||
uint _quorumId
|
||||
) external view returns (address[] memory);
|
||||
|
||||
function getQuorumRow(
|
||||
uint _epoch,
|
||||
uint _quorumId,
|
||||
uint32 _rowIndex
|
||||
) external view returns (address);
|
||||
|
||||
function registerSigner(
|
||||
SignerDetail memory _signer,
|
||||
BN254.G1Point memory _signature
|
||||
) external;
|
||||
|
||||
function updateSocket(string memory _socket) external;
|
||||
|
||||
function registeredEpoch(
|
||||
address _account,
|
||||
uint _epoch
|
||||
) external view returns (bool);
|
||||
|
||||
function registerNextEpoch(BN254.G1Point memory _signature) external;
|
||||
|
||||
function getAggPkG1(
|
||||
uint _epoch,
|
||||
uint _quorumId,
|
||||
bytes memory _quorumBitmap
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (BN254.G1Point memory aggPkG1, uint total, uint hit);
|
||||
}
|
416
precompiles/interfaces/contracts/IStaking.sol
Normal file
416
precompiles/interfaces/contracts/IStaking.sol
Normal file
@ -0,0 +1,416 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
pragma solidity >=0.8.0;
|
||||
|
||||
/**
|
||||
* @dev Description defines a validator description
|
||||
*/
|
||||
struct Description {
|
||||
string moniker;
|
||||
string identity;
|
||||
string website;
|
||||
string securityContact;
|
||||
string details;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev CommissionRates defines the initial commission rates to be used for creating
|
||||
* a validator.
|
||||
*/
|
||||
struct CommissionRates {
|
||||
uint rate; // 18 decimals
|
||||
uint maxRate; // 18 decimals
|
||||
uint maxChangeRate; // 18 decimals
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @dev Commission defines the commission parameters.
|
||||
*/
|
||||
struct Commission {
|
||||
CommissionRates commissionRates;
|
||||
uint updateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Validator defines a validator.
|
||||
*/
|
||||
struct Validator {
|
||||
string operatorAddress;
|
||||
string consensusPubkey;
|
||||
bool jailed;
|
||||
BondStatus status;
|
||||
uint tokens;
|
||||
uint delegatorShares; // 18 decimals
|
||||
Description description;
|
||||
int64 unbondingHeight;
|
||||
int64 unbondingTime;
|
||||
Commission commission;
|
||||
uint minSelfDelegation;
|
||||
int64 unbondingOnHoldRefCount;
|
||||
uint64[] unbondingIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Delegation represents the bond with tokens held by an account.
|
||||
*/
|
||||
struct Delegation {
|
||||
string delegatorAddress;
|
||||
string validatorAddress;
|
||||
uint shares; // 18 decimals
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev RedelegationResponse is equivalent to a Redelegation except that its entries
|
||||
* contain a balance in addition to shares which is more suitable for client
|
||||
* responses.
|
||||
*/
|
||||
struct DelegationResponse {
|
||||
Delegation delegation;
|
||||
uint balance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev UnbondingDelegationEntry defines an unbonding object with relevant metadata.
|
||||
*/
|
||||
struct UnbondingDelegationEntry {
|
||||
int64 creationHeight;
|
||||
int64 completionTime;
|
||||
uint initialBalance;
|
||||
uint balance;
|
||||
uint64 unbondingId;
|
||||
int64 unbondingOnHoldRefCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev UnbondingDelegation stores all of a single delegator's unbonding bonds
|
||||
* for a single validator in an time-ordered list.
|
||||
*/
|
||||
struct UnbondingDelegation {
|
||||
string delegatorAddress;
|
||||
string validatorAddress;
|
||||
UnbondingDelegationEntry[] entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev RedelegationResponse is equivalent to a Redelegation except that its entries
|
||||
* contain a balance in addition to shares which is more suitable for client
|
||||
* responses.
|
||||
*/
|
||||
struct RedelegationResponse {
|
||||
Redelegation redelegation;
|
||||
RedelegationEntryResponse[] entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Redelegation contains the list of a particular delegator's redelegating bonds
|
||||
* from a particular source validator to a particular destination validator.
|
||||
*/
|
||||
struct Redelegation {
|
||||
string delegatorAddress;
|
||||
string validatorSrcAddress;
|
||||
string validatorDstAddress;
|
||||
RedelegationEntry[] entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev RedelegationEntry defines a redelegation object with relevant metadata.
|
||||
*/
|
||||
struct RedelegationEntry {
|
||||
int64 creationHeight;
|
||||
int64 completionTime;
|
||||
uint initialBalance;
|
||||
uint sharesDst; // 18 decimals
|
||||
uint64 unbondingId;
|
||||
int64 unbondingOnHoldRefCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev RedelegationEntryResponse is equivalent to a RedelegationEntry except that it
|
||||
* contains a balance in addition to shares which is more suitable for client
|
||||
* responses.
|
||||
*/
|
||||
struct RedelegationEntryResponse {
|
||||
RedelegationEntry redelegationEntry;
|
||||
uint balance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Params defines the parameters for the x/staking module.
|
||||
*/
|
||||
struct Params {
|
||||
int64 unbondingTime;
|
||||
uint32 maxValidators;
|
||||
uint32 maxEntries;
|
||||
uint32 historicalEntries;
|
||||
string bondDenom;
|
||||
uint minCommissionRate; // 18 decimals
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev BondStatus is the status of a validator.
|
||||
*/
|
||||
enum BondStatus {
|
||||
Unspecified,
|
||||
Unbonded,
|
||||
Unbonding,
|
||||
Bonded
|
||||
}
|
||||
|
||||
struct NullableUint {
|
||||
bool isNull;
|
||||
uint value;
|
||||
}
|
||||
|
||||
struct PageRequest {
|
||||
bytes key;
|
||||
uint64 offset;
|
||||
uint64 limit;
|
||||
bool countTotal;
|
||||
bool reverse;
|
||||
}
|
||||
|
||||
struct PageResponse {
|
||||
bytes nextKey;
|
||||
uint64 total;
|
||||
}
|
||||
|
||||
interface IStaking {
|
||||
/*=== cosmos tx ===*/
|
||||
|
||||
/**
|
||||
* @dev CreateValidator defines a method for creating a new validator for tx sender.
|
||||
* cosmos grpc: rpc CreateValidator(MsgCreateValidator) returns (MsgCreateValidatorResponse);
|
||||
*/
|
||||
function createValidator(
|
||||
Description memory description,
|
||||
CommissionRates memory commission,
|
||||
uint minSelfDelegation,
|
||||
string memory pubkey,
|
||||
uint value
|
||||
) external;
|
||||
|
||||
/**
|
||||
* @dev EditValidator defines a method for editing an existing validator (tx sender).
|
||||
* cosmos grpc: rpc EditValidator(MsgEditValidator) returns (MsgEditValidatorResponse);
|
||||
*/
|
||||
function editValidator(
|
||||
Description memory description,
|
||||
NullableUint memory commissionRate,
|
||||
NullableUint memory minSelfDelegation
|
||||
) external;
|
||||
|
||||
/**
|
||||
* @dev Delegate defines a method for performing a delegation of coins from a delegator to a validator.abi
|
||||
* The delegator is tx sender.
|
||||
* cosmos grpc: rpc Delegate(MsgDelegate) returns (MsgDelegateResponse);
|
||||
*/
|
||||
function delegate(
|
||||
string memory validatorAddress,
|
||||
uint amount // in bond denom
|
||||
) external returns (bool success);
|
||||
|
||||
/**
|
||||
* @dev BeginRedelegate defines a method for performing a redelegationA
|
||||
* of coins from a delegator and source validator to a destination validator.
|
||||
* The delegator is tx sender.
|
||||
* cosmos grpc: rpc BeginRedelegate(MsgBeginRedelegate) returns (MsgBeginRedelegateResponse);
|
||||
*/
|
||||
function beginRedelegate(
|
||||
string memory validatorSrcAddress,
|
||||
string memory validatorDstAddress,
|
||||
uint amount // in bond denom
|
||||
) external returns (uint completionTime);
|
||||
|
||||
/**
|
||||
* @dev Undelegate defines a method for performing an undelegation from a
|
||||
* delegate and a validator.
|
||||
* The delegator is tx sender.
|
||||
* cosmos grpc: rpc Undelegate(MsgUndelegate) returns (MsgUndelegateResponse);
|
||||
*/
|
||||
function undelegate(
|
||||
string memory validatorAddress,
|
||||
uint amount // in bond denom
|
||||
) external returns (uint completionTime);
|
||||
|
||||
/**
|
||||
* @dev CancelUnbondingDelegation defines a method for performing canceling the unbonding delegation
|
||||
* and delegate back to previous validator.
|
||||
* The delegator is tx sender.
|
||||
* Since: cosmos-sdk 0.46
|
||||
* cosmos grpc: rpc CancelUnbondingDelegation(MsgCancelUnbondingDelegation) returns (MsgCancelUnbondingDelegationResponse);
|
||||
*/
|
||||
function cancelUnbondingDelegation(
|
||||
string memory validatorAddress,
|
||||
uint amount, // in bond denom
|
||||
uint creationHeight
|
||||
) external;
|
||||
|
||||
/**
|
||||
* @dev UpdateParams defines an operation for updating the x/staking module parameters.
|
||||
* Since: cosmos-sdk 0.47
|
||||
* grpc: rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse);
|
||||
*/
|
||||
// Skipped. This function is controlled by governance module.
|
||||
|
||||
/*=== cosmos query ===*/
|
||||
|
||||
/**
|
||||
* @dev Validators queries all validators that match the given status.
|
||||
* cosmos grpc: rpc Validators(QueryValidatorsRequest) returns (QueryValidatorsResponse);
|
||||
*/
|
||||
function validators(
|
||||
string memory status,
|
||||
PageRequest memory pagination
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
Validator[] memory validators,
|
||||
PageResponse memory paginationResult
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev Validator queries validator info for given validator address.
|
||||
* cosmos grpc: rpc Validator(QueryValidatorRequest) returns (QueryValidatorResponse);
|
||||
*/
|
||||
function validator(
|
||||
string memory validatorAddress
|
||||
) external view returns (Validator memory validator);
|
||||
|
||||
/**
|
||||
* @dev ValidatorDelegations queries delegate info for given validator.
|
||||
* cosmos grpc: rpc ValidatorDelegations(QueryValidatorDelegationsRequest) returns (QueryValidatorDelegationsResponse);
|
||||
*/
|
||||
function validatorDelegations(
|
||||
string memory validatorAddr,
|
||||
PageRequest memory pagination
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
DelegationResponse[] memory delegationResponses,
|
||||
PageResponse memory paginationResult
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev ValidatorUnbondingDelegations queries unbonding delegations of a validator.
|
||||
* cosmos grpc: rpc ValidatorUnbondingDelegations(QueryValidatorUnbondingDelegationsRequest) returns (QueryValidatorUnbondingDelegationsResponse);
|
||||
*/
|
||||
//
|
||||
function validatorUnbondingDelegations(
|
||||
string memory validatorAddr,
|
||||
PageRequest memory pagination
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
UnbondingDelegation[] memory unbondingResponses,
|
||||
PageResponse memory paginationResult
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev Delegation queries delegate info for given validator delegator pair.
|
||||
* cosmos grpc: rpc Delegation(QueryDelegationRequest) returns (QueryDelegationResponse);
|
||||
*/
|
||||
function delegation(
|
||||
string memory delegatorAddr,
|
||||
string memory validatorAddr
|
||||
) external view returns (Delegation memory delegation, uint balance);
|
||||
|
||||
/**
|
||||
* @dev UnbondingDelegation queries unbonding info for given validator delegator pair.
|
||||
* cosmos grpc: rpc UnbondingDelegation(QueryUnbondingDelegationRequest) returns (QueryUnbondingDelegationResponse);
|
||||
*/
|
||||
function unbondingDelegation(
|
||||
string memory delegatorAddr,
|
||||
string memory validatorAddr
|
||||
) external view returns (UnbondingDelegation memory unbond);
|
||||
|
||||
/**
|
||||
* @dev DelegatorDelegations queries all delegations of a given delegator address.
|
||||
*
|
||||
* cosmos grpc: rpc DelegatorDelegations(QueryDelegatorDelegationsRequest) returns (QueryDelegatorDelegationsResponse);
|
||||
*/
|
||||
function delegatorDelegations(
|
||||
string memory delegatorAddr,
|
||||
PageRequest memory pagination
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
DelegationResponse[] memory delegationResponses,
|
||||
PageResponse memory paginationResult
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev DelegatorUnbondingDelegations queries all unbonding delegations of a given delegator address.
|
||||
* cosmos grpc: rpc DelegatorUnbondingDelegations(QueryDelegatorUnbondingDelegationsRequest)
|
||||
*/
|
||||
function delegatorUnbondingDelegations(
|
||||
string memory delegatorAddr,
|
||||
PageRequest memory pagination
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
UnbondingDelegation[] memory unbondingResponses,
|
||||
PageResponse memory paginationResult
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev Redelegations queries redelegations of given address.
|
||||
*
|
||||
* grpc: rpc Redelegations(QueryRedelegationsRequest) returns (QueryRedelegationsResponse);
|
||||
*/
|
||||
function redelegations(
|
||||
string memory delegatorAddress,
|
||||
string memory srcValidatorAddress,
|
||||
string memory dstValidatorAddress,
|
||||
PageRequest calldata pageRequest
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
RedelegationResponse[] calldata redelegationResponses,
|
||||
PageResponse calldata paginationResult
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev DelegatorValidators queries all validators info for given delegator address.
|
||||
* cosmos grpc: rpc DelegatorValidators(QueryDelegatorValidatorsRequest) returns (QueryDelegatorValidatorsResponse);
|
||||
*/
|
||||
function delegatorValidators(
|
||||
string memory delegatorAddr,
|
||||
PageRequest memory pagination
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
Validator[] memory validators,
|
||||
PageResponse memory paginationResult
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev DelegatorValidator queries validator info for given delegator validator pair.
|
||||
* cosmos grpc: rpc DelegatorValidator(QueryDelegatorValidatorRequest) returns (QueryDelegatorValidatorResponse);
|
||||
*/
|
||||
function delegatorValidator(
|
||||
string memory delegatorAddr,
|
||||
string memory validatorAddr
|
||||
) external view returns (Validator memory validator);
|
||||
|
||||
/**
|
||||
* @dev Pool queries the pool info.
|
||||
* cosmos grpc: rpc Pool(QueryPoolRequest) returns (QueryPoolResponse);
|
||||
*/
|
||||
function pool()
|
||||
external
|
||||
view
|
||||
returns (uint notBondedTokens, uint bondedTokens);
|
||||
|
||||
/**
|
||||
* @dev Parameters queries the staking parameters.
|
||||
* cosmos grpc: rpc Params(QueryParamsRequest) returns (QueryParamsResponse);
|
||||
*/
|
||||
function params() external view returns (Params memory params);
|
||||
}
|
33
precompiles/interfaces/hardhat.config.ts
Normal file
33
precompiles/interfaces/hardhat.config.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import "hardhat-abi-exporter";
|
||||
import { HardhatUserConfig } from "hardhat/types";
|
||||
|
||||
const config: HardhatUserConfig = {
|
||||
paths: {
|
||||
artifacts: "build/artifacts",
|
||||
cache: "build/cache",
|
||||
sources: "contracts",
|
||||
},
|
||||
solidity: {
|
||||
compilers: [
|
||||
{
|
||||
version: "0.8.20",
|
||||
settings: {
|
||||
evmVersion: "london",
|
||||
optimizer: {
|
||||
enabled: true,
|
||||
runs: 200,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
abiExporter: {
|
||||
path: "./abis",
|
||||
runOnCompile: true,
|
||||
clear: true,
|
||||
flat: true,
|
||||
format: "json",
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
27
precompiles/interfaces/package.json
Normal file
27
precompiles/interfaces/package.json
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "precompile-contracts",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"build": "hardhat compile",
|
||||
"fmt:sol": "prettier 'contracts/**/*.sol' -w"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nomicfoundation/hardhat-ethers": "^3.0.5",
|
||||
"@typescript-eslint/eslint-plugin": "6.21.0",
|
||||
"@typescript-eslint/parser": "6.21.0",
|
||||
"eslint": "8.34.0",
|
||||
"eslint-config-prettier": "8.6.0",
|
||||
"eslint-plugin-no-only-tests": "3.1.0",
|
||||
"eslint-plugin-prettier": "4.2.1",
|
||||
"hardhat": "^2.22.2",
|
||||
"hardhat-abi-exporter": "^2.10.1",
|
||||
"prettier": "2.8.4",
|
||||
"prettier-plugin-organize-imports": "3.2.4",
|
||||
"prettier-plugin-solidity": "1.1.2",
|
||||
"solhint": "^4.5.4",
|
||||
"solhint-plugin-prettier": "0.0.5",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "4.9.5"
|
||||
}
|
||||
}
|
3152
precompiles/interfaces/yarn.lock
Normal file
3152
precompiles/interfaces/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
1722
precompiles/staking/IStaking.abi
Normal file
1722
precompiles/staking/IStaking.abi
Normal file
File diff suppressed because it is too large
Load Diff
835
precompiles/staking/contract.go
Normal file
835
precompiles/staking/contract.go
Normal file
File diff suppressed because one or more lines are too long
5
precompiles/staking/errors.go
Normal file
5
precompiles/staking/errors.go
Normal file
@ -0,0 +1,5 @@
|
||||
package staking
|
||||
|
||||
const (
|
||||
ErrPubKeyInvalidLength = "public key with invalid length"
|
||||
)
|
223
precompiles/staking/query.go
Normal file
223
precompiles/staking/query.go
Normal file
@ -0,0 +1,223 @@
|
||||
package staking
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
)
|
||||
|
||||
func (s *StakingPrecompile) Validators(ctx sdk.Context, _ *vm.EVM, method *abi.Method, args []interface{}) ([]byte, error) {
|
||||
req, err := NewQueryValidatorsRequest(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err := stakingkeeper.Querier{Keeper: s.stakingKeeper}.Validators(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
validators := make([]Validator, len(response.Validators))
|
||||
for i, v := range response.Validators {
|
||||
validators[i] = convertValidator(v)
|
||||
}
|
||||
paginationResult := convertPageResponse(response.Pagination)
|
||||
|
||||
return method.Outputs.Pack(validators, paginationResult)
|
||||
}
|
||||
|
||||
func (s *StakingPrecompile) Validator(ctx sdk.Context, _ *vm.EVM, method *abi.Method, args []interface{}) ([]byte, error) {
|
||||
req, err := NewQueryValidatorRequest(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err := stakingkeeper.Querier{Keeper: s.stakingKeeper}.Validator(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return method.Outputs.Pack(convertValidator(response.Validator))
|
||||
}
|
||||
|
||||
func (s *StakingPrecompile) ValidatorDelegations(ctx sdk.Context, _ *vm.EVM, method *abi.Method, args []interface{}) ([]byte, error) {
|
||||
req, err := NewQueryValidatorDelegationsRequest(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err := stakingkeeper.Querier{Keeper: s.stakingKeeper}.ValidatorDelegations(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
delegationResponses := make([]DelegationResponse, len(response.DelegationResponses))
|
||||
for i, v := range response.DelegationResponses {
|
||||
delegationResponses[i] = convertDelegationResponse(v)
|
||||
}
|
||||
paginationResult := convertPageResponse(response.Pagination)
|
||||
|
||||
return method.Outputs.Pack(delegationResponses, paginationResult)
|
||||
}
|
||||
|
||||
func (s *StakingPrecompile) ValidatorUnbondingDelegations(ctx sdk.Context, _ *vm.EVM, method *abi.Method, args []interface{}) ([]byte, error) {
|
||||
req, err := NewQueryValidatorUnbondingDelegationsRequest(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err := stakingkeeper.Querier{Keeper: s.stakingKeeper}.ValidatorUnbondingDelegations(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
unbondingResponses := make([]UnbondingDelegation, len(response.UnbondingResponses))
|
||||
for i, v := range response.UnbondingResponses {
|
||||
unbondingResponses[i] = convertUnbondingDelegation(v)
|
||||
}
|
||||
paginationResult := convertPageResponse(response.Pagination)
|
||||
|
||||
return method.Outputs.Pack(unbondingResponses, paginationResult)
|
||||
}
|
||||
|
||||
func (s *StakingPrecompile) Delegation(ctx sdk.Context, _ *vm.EVM, method *abi.Method, args []interface{}) ([]byte, error) {
|
||||
req, err := NewQueryDelegationRequest(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err := stakingkeeper.Querier{Keeper: s.stakingKeeper}.Delegation(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
delegation := convertDelegation(response.DelegationResponse.Delegation)
|
||||
balance := response.DelegationResponse.Balance.Amount.BigInt()
|
||||
|
||||
return method.Outputs.Pack(delegation, balance)
|
||||
}
|
||||
|
||||
func (s *StakingPrecompile) UnbondingDelegation(ctx sdk.Context, _ *vm.EVM, method *abi.Method, args []interface{}) ([]byte, error) {
|
||||
req, err := NewQueryUnbondingDelegationRequest(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err := stakingkeeper.Querier{Keeper: s.stakingKeeper}.UnbondingDelegation(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return method.Outputs.Pack(convertUnbondingDelegation(response.Unbond))
|
||||
}
|
||||
|
||||
func (s *StakingPrecompile) DelegatorDelegations(ctx sdk.Context, _ *vm.EVM, method *abi.Method, args []interface{}) ([]byte, error) {
|
||||
req, err := NewQueryDelegatorDelegationsRequest(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err := stakingkeeper.Querier{Keeper: s.stakingKeeper}.DelegatorDelegations(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
delegationResponses := make([]DelegationResponse, len(response.DelegationResponses))
|
||||
for i, v := range response.DelegationResponses {
|
||||
delegationResponses[i] = convertDelegationResponse(v)
|
||||
}
|
||||
paginationResult := convertPageResponse(response.Pagination)
|
||||
|
||||
return method.Outputs.Pack(delegationResponses, paginationResult)
|
||||
}
|
||||
|
||||
func (s *StakingPrecompile) DelegatorUnbondingDelegations(ctx sdk.Context, _ *vm.EVM, method *abi.Method, args []interface{}) ([]byte, error) {
|
||||
req, err := NewQueryDelegatorUnbondingDelegationsRequest(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err := stakingkeeper.Querier{Keeper: s.stakingKeeper}.DelegatorUnbondingDelegations(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
unbondingResponses := make([]UnbondingDelegation, len(response.UnbondingResponses))
|
||||
for i, v := range response.UnbondingResponses {
|
||||
unbondingResponses[i] = convertUnbondingDelegation(v)
|
||||
}
|
||||
paginationResult := convertPageResponse(response.Pagination)
|
||||
|
||||
return method.Outputs.Pack(unbondingResponses, paginationResult)
|
||||
}
|
||||
|
||||
func (s *StakingPrecompile) Redelegations(ctx sdk.Context, _ *vm.EVM, method *abi.Method, args []interface{}) ([]byte, error) {
|
||||
req, err := NewQueryRedelegationsRequest(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err := stakingkeeper.Querier{Keeper: s.stakingKeeper}.Redelegations(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
redelegationResponses := make([]RedelegationResponse, len(response.RedelegationResponses))
|
||||
for i, v := range response.RedelegationResponses {
|
||||
redelegationResponses[i] = convertRedelegationResponse(v)
|
||||
}
|
||||
paginationResult := convertPageResponse(response.Pagination)
|
||||
|
||||
return method.Outputs.Pack(redelegationResponses, paginationResult)
|
||||
}
|
||||
|
||||
func (s *StakingPrecompile) DelegatorValidators(ctx sdk.Context, _ *vm.EVM, method *abi.Method, args []interface{}) ([]byte, error) {
|
||||
req, err := NewQueryDelegatorValidatorsRequest(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err := stakingkeeper.Querier{Keeper: s.stakingKeeper}.DelegatorValidators(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
validators := make([]Validator, len(response.Validators))
|
||||
for i, v := range response.Validators {
|
||||
validators[i] = convertValidator(v)
|
||||
}
|
||||
paginationResult := convertPageResponse(response.Pagination)
|
||||
|
||||
return method.Outputs.Pack(validators, paginationResult)
|
||||
}
|
||||
|
||||
func (s *StakingPrecompile) DelegatorValidator(ctx sdk.Context, _ *vm.EVM, method *abi.Method, args []interface{}) ([]byte, error) {
|
||||
req, err := NewQueryDelegatorValidatorRequest(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err := stakingkeeper.Querier{Keeper: s.stakingKeeper}.DelegatorValidator(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return method.Outputs.Pack(convertValidator(response.Validator))
|
||||
}
|
||||
|
||||
func (s *StakingPrecompile) Pool(ctx sdk.Context, _ *vm.EVM, method *abi.Method, args []interface{}) ([]byte, error) {
|
||||
req, err := NewQueryPoolRequest(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err := stakingkeeper.Querier{Keeper: s.stakingKeeper}.Pool(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
notBondedTokens := response.Pool.NotBondedTokens.BigInt()
|
||||
bondedTokens := response.Pool.BondedTokens.BigInt()
|
||||
|
||||
return method.Outputs.Pack(notBondedTokens, bondedTokens)
|
||||
}
|
||||
|
||||
func (s *StakingPrecompile) Params(ctx sdk.Context, _ *vm.EVM, method *abi.Method, args []interface{}) ([]byte, error) {
|
||||
req, err := NewQueryParamsRequest(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err := stakingkeeper.Querier{Keeper: s.stakingKeeper}.Params(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return method.Outputs.Pack(convertParams(response.Params))
|
||||
}
|
148
precompiles/staking/staking.go
Normal file
148
precompiles/staking/staking.go
Normal file
@ -0,0 +1,148 @@
|
||||
package staking
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
precopmiles_common "github.com/0glabs/0g-chain/precompiles/common"
|
||||
"github.com/cosmos/cosmos-sdk/store/types"
|
||||
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/evmos/ethermint/x/evm/statedb"
|
||||
)
|
||||
|
||||
const (
|
||||
PrecompileAddress = "0x0000000000000000000000000000000000001001"
|
||||
|
||||
// txs
|
||||
StakingFunctionCreateValidator = "createValidator"
|
||||
StakingFunctionEditValidator = "editValidator"
|
||||
StakingFunctionDelegate = "delegate"
|
||||
StakingFunctionBeginRedelegate = "beginRedelegate"
|
||||
StakingFunctionUndelegate = "undelegate"
|
||||
StakingFunctionCancelUnbondingDelegation = "cancelUnbondingDelegation"
|
||||
// queries
|
||||
StakingFunctionValidators = "validators"
|
||||
StakingFunctionValidator = "validator"
|
||||
StakingFunctionValidatorDelegations = "validatorDelegations"
|
||||
StakingFunctionValidatorUnbondingDelegations = "validatorUnbondingDelegations"
|
||||
StakingFunctionDelegation = "delegation"
|
||||
StakingFunctionUnbondingDelegation = "unbondingDelegation"
|
||||
StakingFunctionDelegatorDelegations = "delegatorDelegations"
|
||||
StakingFunctionDelegatorUnbondingDelegations = "delegatorUnbondingDelegations"
|
||||
StakingFunctionRedelegations = "redelegations"
|
||||
StakingFunctionDelegatorValidators = "delegatorValidators"
|
||||
StakingFunctionDelegatorValidator = "delegatorValidator"
|
||||
StakingFunctionPool = "pool"
|
||||
StakingFunctionParams = "params"
|
||||
)
|
||||
|
||||
var _ vm.PrecompiledContract = &StakingPrecompile{}
|
||||
|
||||
type StakingPrecompile struct {
|
||||
abi abi.ABI
|
||||
stakingKeeper *stakingkeeper.Keeper
|
||||
}
|
||||
|
||||
func NewStakingPrecompile(stakingKeeper *stakingkeeper.Keeper) (*StakingPrecompile, error) {
|
||||
abi, err := abi.JSON(strings.NewReader(StakingABI))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &StakingPrecompile{
|
||||
abi: abi,
|
||||
stakingKeeper: stakingKeeper,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Address implements vm.PrecompiledContract.
|
||||
func (s *StakingPrecompile) Address() common.Address {
|
||||
return common.HexToAddress(PrecompileAddress)
|
||||
}
|
||||
|
||||
// RequiredGas implements vm.PrecompiledContract.
|
||||
func (s *StakingPrecompile) RequiredGas(input []byte) uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// Run implements vm.PrecompiledContract.
|
||||
func (s *StakingPrecompile) Run(evm *vm.EVM, contract *vm.Contract, readonly bool) ([]byte, error) {
|
||||
// parse input
|
||||
if len(contract.Input) < 4 {
|
||||
return nil, vm.ErrExecutionReverted
|
||||
}
|
||||
method, err := s.abi.MethodById(contract.Input[:4])
|
||||
if err != nil {
|
||||
return nil, vm.ErrExecutionReverted
|
||||
}
|
||||
args, err := method.Inputs.Unpack(contract.Input[4:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// get state db and context
|
||||
stateDB, ok := evm.StateDB.(*statedb.StateDB)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrGetStateDB)
|
||||
}
|
||||
ctx := stateDB.GetContext()
|
||||
// reset gas config
|
||||
ctx = ctx.WithKVGasConfig(types.KVGasConfig())
|
||||
initialGas := ctx.GasMeter().GasConsumed()
|
||||
|
||||
var bz []byte
|
||||
switch method.Name {
|
||||
// queries
|
||||
case StakingFunctionValidators:
|
||||
bz, err = s.Validators(ctx, evm, method, args)
|
||||
case StakingFunctionValidator:
|
||||
bz, err = s.Validator(ctx, evm, method, args)
|
||||
case StakingFunctionValidatorDelegations:
|
||||
bz, err = s.ValidatorDelegations(ctx, evm, method, args)
|
||||
case StakingFunctionValidatorUnbondingDelegations:
|
||||
bz, err = s.ValidatorUnbondingDelegations(ctx, evm, method, args)
|
||||
case StakingFunctionDelegation:
|
||||
bz, err = s.Delegation(ctx, evm, method, args)
|
||||
case StakingFunctionUnbondingDelegation:
|
||||
bz, err = s.UnbondingDelegation(ctx, evm, method, args)
|
||||
case StakingFunctionDelegatorDelegations:
|
||||
bz, err = s.DelegatorDelegations(ctx, evm, method, args)
|
||||
case StakingFunctionDelegatorUnbondingDelegations:
|
||||
bz, err = s.DelegatorUnbondingDelegations(ctx, evm, method, args)
|
||||
case StakingFunctionRedelegations:
|
||||
bz, err = s.Redelegations(ctx, evm, method, args)
|
||||
case StakingFunctionDelegatorValidators:
|
||||
bz, err = s.DelegatorValidators(ctx, evm, method, args)
|
||||
case StakingFunctionDelegatorValidator:
|
||||
bz, err = s.DelegatorValidator(ctx, evm, method, args)
|
||||
case StakingFunctionPool:
|
||||
bz, err = s.Pool(ctx, evm, method, args)
|
||||
case StakingFunctionParams:
|
||||
bz, err = s.Params(ctx, evm, method, args)
|
||||
// txs
|
||||
case StakingFunctionCreateValidator:
|
||||
bz, err = s.CreateValidator(ctx, evm, stateDB, contract, method, args)
|
||||
case StakingFunctionEditValidator:
|
||||
bz, err = s.EditValidator(ctx, evm, stateDB, contract, method, args)
|
||||
case StakingFunctionDelegate:
|
||||
bz, err = s.Delegate(ctx, evm, stateDB, contract, method, args)
|
||||
case StakingFunctionBeginRedelegate:
|
||||
bz, err = s.BeginRedelegate(ctx, evm, stateDB, contract, method, args)
|
||||
case StakingFunctionUndelegate:
|
||||
bz, err = s.Undelegate(ctx, evm, stateDB, contract, method, args)
|
||||
case StakingFunctionCancelUnbondingDelegation:
|
||||
bz, err = s.CancelUnbondingDelegation(ctx, evm, stateDB, contract, method, args)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cost := ctx.GasMeter().GasConsumed() - initialGas
|
||||
|
||||
if !contract.UseGas(cost) {
|
||||
return nil, vm.ErrOutOfGas
|
||||
}
|
||||
return bz, nil
|
||||
}
|
162
precompiles/staking/tx.go
Normal file
162
precompiles/staking/tx.go
Normal file
@ -0,0 +1,162 @@
|
||||
package staking
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
precopmiles_common "github.com/0glabs/0g-chain/precompiles/common"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/evmos/ethermint/x/evm/statedb"
|
||||
)
|
||||
|
||||
func (s *StakingPrecompile) CreateValidator(
|
||||
ctx sdk.Context,
|
||||
evm *vm.EVM,
|
||||
stateDB *statedb.StateDB,
|
||||
contract *vm.Contract,
|
||||
method *abi.Method,
|
||||
args []interface{},
|
||||
) ([]byte, error) {
|
||||
msg, err := NewMsgCreateValidator(args, evm.Origin, s.stakingKeeper.BondDenom(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// validation
|
||||
if contract.CallerAddress != evm.Origin {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrSenderNotOrigin)
|
||||
}
|
||||
// execute
|
||||
_, err = stakingkeeper.NewMsgServerImpl(s.stakingKeeper).CreateValidator(ctx, msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// emit events
|
||||
return method.Outputs.Pack()
|
||||
}
|
||||
|
||||
func (s *StakingPrecompile) EditValidator(
|
||||
ctx sdk.Context,
|
||||
evm *vm.EVM,
|
||||
stateDB *statedb.StateDB,
|
||||
contract *vm.Contract,
|
||||
method *abi.Method,
|
||||
args []interface{},
|
||||
) ([]byte, error) {
|
||||
msg, err := NewMsgEditValidator(args, evm.Origin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// validation
|
||||
if contract.CallerAddress != evm.Origin {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrSenderNotOrigin)
|
||||
}
|
||||
// execute
|
||||
_, err = stakingkeeper.NewMsgServerImpl(s.stakingKeeper).EditValidator(ctx, msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// emit events
|
||||
return method.Outputs.Pack()
|
||||
}
|
||||
|
||||
func (s *StakingPrecompile) Delegate(
|
||||
ctx sdk.Context,
|
||||
evm *vm.EVM,
|
||||
stateDB *statedb.StateDB,
|
||||
contract *vm.Contract,
|
||||
method *abi.Method,
|
||||
args []interface{},
|
||||
) ([]byte, error) {
|
||||
msg, err := NewMsgDelegate(args, evm.Origin, s.stakingKeeper.BondDenom(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// validation
|
||||
if contract.CallerAddress != evm.Origin {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrSenderNotOrigin)
|
||||
}
|
||||
// execute
|
||||
_, err = stakingkeeper.NewMsgServerImpl(s.stakingKeeper).Delegate(ctx, msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// emit events
|
||||
return method.Outputs.Pack()
|
||||
}
|
||||
|
||||
func (s *StakingPrecompile) BeginRedelegate(
|
||||
ctx sdk.Context,
|
||||
evm *vm.EVM,
|
||||
stateDB *statedb.StateDB,
|
||||
contract *vm.Contract,
|
||||
method *abi.Method,
|
||||
args []interface{},
|
||||
) ([]byte, error) {
|
||||
msg, err := NewMsgBeginRedelegate(args, evm.Origin, s.stakingKeeper.BondDenom(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// validation
|
||||
if contract.CallerAddress != evm.Origin {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrSenderNotOrigin)
|
||||
}
|
||||
// execute
|
||||
_, err = stakingkeeper.NewMsgServerImpl(s.stakingKeeper).BeginRedelegate(ctx, msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// emit events
|
||||
return method.Outputs.Pack()
|
||||
}
|
||||
|
||||
func (s *StakingPrecompile) Undelegate(
|
||||
ctx sdk.Context,
|
||||
evm *vm.EVM,
|
||||
stateDB *statedb.StateDB,
|
||||
contract *vm.Contract,
|
||||
method *abi.Method,
|
||||
args []interface{},
|
||||
) ([]byte, error) {
|
||||
msg, err := NewMsgUndelegate(args, evm.Origin, s.stakingKeeper.BondDenom(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// validation
|
||||
if contract.CallerAddress != evm.Origin {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrSenderNotOrigin)
|
||||
}
|
||||
// execute
|
||||
_, err = stakingkeeper.NewMsgServerImpl(s.stakingKeeper).Undelegate(ctx, msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// emit events
|
||||
return method.Outputs.Pack()
|
||||
}
|
||||
|
||||
func (s *StakingPrecompile) CancelUnbondingDelegation(
|
||||
ctx sdk.Context,
|
||||
evm *vm.EVM,
|
||||
stateDB *statedb.StateDB,
|
||||
contract *vm.Contract,
|
||||
method *abi.Method,
|
||||
args []interface{},
|
||||
) ([]byte, error) {
|
||||
msg, err := NewMsgCancelUnbondingDelegation(args, evm.Origin, s.stakingKeeper.BondDenom(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// validation
|
||||
if contract.CallerAddress != evm.Origin {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrSenderNotOrigin)
|
||||
}
|
||||
// execute
|
||||
_, err = stakingkeeper.NewMsgServerImpl(s.stakingKeeper).CancelUnbondingDelegation(ctx, msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// emit events
|
||||
return method.Outputs.Pack()
|
||||
}
|
590
precompiles/staking/types.go
Normal file
590
precompiles/staking/types.go
Normal file
@ -0,0 +1,590 @@
|
||||
package staking
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
precopmiles_common "github.com/0glabs/0g-chain/precompiles/common"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
query "github.com/cosmos/cosmos-sdk/types/query"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
||||
type Commission struct {
|
||||
CommissionRates CommissionRates `json:"commissionRates"`
|
||||
UpdateTime *big.Int `json:"updateTime"`
|
||||
}
|
||||
|
||||
type CommissionRates struct {
|
||||
Rate *big.Int `json:"rate"`
|
||||
MaxRate *big.Int `json:"maxRate"`
|
||||
MaxChangeRate *big.Int `json:"maxChangeRate"`
|
||||
}
|
||||
|
||||
type Delegation struct {
|
||||
DelegatorAddress string `json:"delegatorAddress"`
|
||||
ValidatorAddress string `json:"validatorAddress"`
|
||||
Shares *big.Int `json:"shares"`
|
||||
}
|
||||
|
||||
type DelegationResponse struct {
|
||||
Delegation Delegation `json:"delegation"`
|
||||
Balance *big.Int `json:"balance"`
|
||||
}
|
||||
|
||||
type Description struct {
|
||||
Moniker string `json:"moniker"`
|
||||
Identity string `json:"identity"`
|
||||
Website string `json:"website"`
|
||||
SecurityContact string `json:"securityContact"`
|
||||
Details string `json:"details"`
|
||||
}
|
||||
|
||||
type NullableUint struct {
|
||||
IsNull bool `json:"isNull"`
|
||||
Value *big.Int `json:"value"`
|
||||
}
|
||||
|
||||
type PageRequest struct {
|
||||
Key []byte `json:"key"`
|
||||
Offset uint64 `json:"offset"`
|
||||
Limit uint64 `json:"limit"`
|
||||
CountTotal bool `json:"countTotal"`
|
||||
Reverse bool `json:"reverse"`
|
||||
}
|
||||
|
||||
type PageResponse struct {
|
||||
NextKey []byte `json:"nextKey"`
|
||||
Total uint64 `json:"total"`
|
||||
}
|
||||
|
||||
type Params struct {
|
||||
UnbondingTime int64 `json:"unbondingTime"`
|
||||
MaxValidators uint32 `json:"maxValidators"`
|
||||
MaxEntries uint32 `json:"maxEntries"`
|
||||
HistoricalEntries uint32 `json:"historicalEntries"`
|
||||
BondDenom string `json:"bondDenom"`
|
||||
MinCommissionRate *big.Int `json:"minCommissionRate"`
|
||||
}
|
||||
|
||||
type Redelegation struct {
|
||||
DelegatorAddress string `json:"delegatorAddress"`
|
||||
ValidatorSrcAddress string `json:"validatorSrcAddress"`
|
||||
ValidatorDstAddress string `json:"validatorDstAddress"`
|
||||
Entries []RedelegationEntry `json:"entries"`
|
||||
}
|
||||
|
||||
type RedelegationEntry struct {
|
||||
CreationHeight int64 `json:"creationHeight"`
|
||||
CompletionTime int64 `json:"completionTime"`
|
||||
InitialBalance *big.Int `json:"initialBalance"`
|
||||
SharesDst *big.Int `json:"sharesDst"`
|
||||
UnbondingId uint64 `json:"unbondingId"`
|
||||
UnbondingOnHoldRefCount int64 `json:"unbondingOnHoldRefCount"`
|
||||
}
|
||||
|
||||
type RedelegationEntryResponse struct {
|
||||
RedelegationEntry RedelegationEntry `json:"redelegationEntry"`
|
||||
Balance *big.Int `json:"balance"`
|
||||
}
|
||||
|
||||
type RedelegationResponse struct {
|
||||
Redelegation Redelegation `json:"redelegation"`
|
||||
Entries []RedelegationEntryResponse `json:"entries"`
|
||||
}
|
||||
|
||||
type UnbondingDelegation struct {
|
||||
DelegatorAddress string `json:"delegatorAddress"`
|
||||
ValidatorAddress string `json:"validatorAddress"`
|
||||
Entries []UnbondingDelegationEntry `json:"entries"`
|
||||
}
|
||||
|
||||
type UnbondingDelegationEntry struct {
|
||||
CreationHeight int64 `json:"creationHeight"`
|
||||
CompletionTime int64 `json:"completionTime"`
|
||||
InitialBalance *big.Int `json:"initialBalance"`
|
||||
Balance *big.Int `json:"balance"`
|
||||
UnbondingId uint64 `json:"unbondingId"`
|
||||
UnbondingOnHoldRefCount int64 `json:"unbondingOnHoldRefCount"`
|
||||
}
|
||||
|
||||
type Validator struct {
|
||||
OperatorAddress string `json:"operatorAddress"`
|
||||
ConsensusPubkey string `json:"consensusPubkey"`
|
||||
Jailed bool `json:"jailed"`
|
||||
Status uint8 `json:"status"`
|
||||
Tokens *big.Int `json:"tokens"`
|
||||
DelegatorShares *big.Int `json:"delegatorShares"`
|
||||
Description Description `json:"description"`
|
||||
UnbondingHeight int64 `json:"unbondingHeight"`
|
||||
UnbondingTime int64 `json:"unbondingTime"`
|
||||
Commission Commission `json:"commission"`
|
||||
MinSelfDelegation *big.Int `json:"minSelfDelegation"`
|
||||
UnbondingOnHoldRefCount int64 `json:"unbondingOnHoldRefCount"`
|
||||
UnbondingIds []uint64 `json:"unbondingIds"`
|
||||
}
|
||||
|
||||
func convertValidator(v stakingtypes.Validator) Validator {
|
||||
validator := Validator{}
|
||||
operatorAddress, err := sdk.ValAddressFromBech32(v.OperatorAddress)
|
||||
if err != nil {
|
||||
validator.OperatorAddress = v.OperatorAddress
|
||||
} else {
|
||||
validator.OperatorAddress = common.BytesToAddress(operatorAddress.Bytes()).String()
|
||||
}
|
||||
|
||||
ed25519pk, ok := v.ConsensusPubkey.GetCachedValue().(cryptotypes.PubKey)
|
||||
if !ok {
|
||||
validator.ConsensusPubkey = v.ConsensusPubkey.String()
|
||||
} else {
|
||||
validator.ConsensusPubkey = base64.StdEncoding.EncodeToString(ed25519pk.Bytes())
|
||||
}
|
||||
|
||||
validator.Jailed = v.Jailed
|
||||
validator.Status = uint8(v.Status)
|
||||
validator.Tokens = v.Tokens.BigInt()
|
||||
validator.DelegatorShares = v.DelegatorShares.BigInt()
|
||||
validator.Description = Description{
|
||||
Moniker: v.Description.Moniker,
|
||||
Identity: v.Description.Identity,
|
||||
Website: v.Description.Website,
|
||||
SecurityContact: v.Description.SecurityContact,
|
||||
Details: v.Description.Details,
|
||||
}
|
||||
validator.UnbondingHeight = v.UnbondingHeight
|
||||
validator.UnbondingTime = v.UnbondingTime.UTC().Unix()
|
||||
validator.Commission = Commission{
|
||||
CommissionRates: convertCommissionRates(v.Commission.CommissionRates),
|
||||
UpdateTime: big.NewInt(v.Commission.UpdateTime.UTC().Unix()),
|
||||
}
|
||||
validator.MinSelfDelegation = v.MinSelfDelegation.BigInt()
|
||||
validator.UnbondingOnHoldRefCount = v.UnbondingOnHoldRefCount
|
||||
validator.UnbondingIds = v.UnbondingIds
|
||||
return validator
|
||||
}
|
||||
|
||||
func convertQueryPageRequest(pagination PageRequest) *query.PageRequest {
|
||||
return &query.PageRequest{
|
||||
Key: pagination.Key,
|
||||
Offset: pagination.Offset,
|
||||
Limit: pagination.Limit,
|
||||
CountTotal: pagination.CountTotal,
|
||||
Reverse: pagination.Reverse,
|
||||
}
|
||||
}
|
||||
|
||||
func convertPageResponse(pagination *query.PageResponse) PageResponse {
|
||||
return PageResponse{
|
||||
NextKey: pagination.NextKey,
|
||||
Total: pagination.Total,
|
||||
}
|
||||
}
|
||||
|
||||
func convertStakingDescription(description Description) stakingtypes.Description {
|
||||
return stakingtypes.Description{
|
||||
Moniker: description.Moniker,
|
||||
Identity: description.Identity,
|
||||
Website: description.Website,
|
||||
SecurityContact: description.SecurityContact,
|
||||
Details: description.Details,
|
||||
}
|
||||
}
|
||||
|
||||
func convertStakingCommissionRates(commission CommissionRates) stakingtypes.CommissionRates {
|
||||
return stakingtypes.CommissionRates{
|
||||
Rate: precopmiles_common.BigIntToLegacyDec(commission.Rate),
|
||||
MaxRate: precopmiles_common.BigIntToLegacyDec(commission.MaxRate),
|
||||
MaxChangeRate: precopmiles_common.BigIntToLegacyDec(commission.MaxChangeRate),
|
||||
}
|
||||
}
|
||||
|
||||
func convertCommissionRates(commission stakingtypes.CommissionRates) CommissionRates {
|
||||
return CommissionRates{
|
||||
Rate: commission.Rate.BigInt(),
|
||||
MaxRate: commission.MaxRate.BigInt(),
|
||||
MaxChangeRate: commission.MaxChangeRate.BigInt(),
|
||||
}
|
||||
}
|
||||
|
||||
func convertDelegation(delegation stakingtypes.Delegation) Delegation {
|
||||
return Delegation{
|
||||
DelegatorAddress: delegation.DelegatorAddress,
|
||||
ValidatorAddress: delegation.ValidatorAddress,
|
||||
Shares: delegation.Shares.BigInt(),
|
||||
}
|
||||
}
|
||||
|
||||
func convertDelegationResponse(response stakingtypes.DelegationResponse) DelegationResponse {
|
||||
return DelegationResponse{
|
||||
Delegation: convertDelegation(response.Delegation),
|
||||
Balance: response.Balance.Amount.BigInt(),
|
||||
}
|
||||
}
|
||||
|
||||
func convertUnbondingDelegationEntry(entry stakingtypes.UnbondingDelegationEntry) UnbondingDelegationEntry {
|
||||
return UnbondingDelegationEntry{
|
||||
CreationHeight: entry.CreationHeight,
|
||||
CompletionTime: entry.CompletionTime.UTC().Unix(),
|
||||
InitialBalance: entry.InitialBalance.BigInt(),
|
||||
Balance: entry.Balance.BigInt(),
|
||||
UnbondingId: entry.UnbondingId,
|
||||
UnbondingOnHoldRefCount: entry.UnbondingOnHoldRefCount,
|
||||
}
|
||||
}
|
||||
|
||||
func convertUnbondingDelegation(response stakingtypes.UnbondingDelegation) UnbondingDelegation {
|
||||
entries := make([]UnbondingDelegationEntry, len(response.Entries))
|
||||
for i, v := range response.Entries {
|
||||
entries[i] = convertUnbondingDelegationEntry(v)
|
||||
}
|
||||
return UnbondingDelegation{
|
||||
DelegatorAddress: response.DelegatorAddress,
|
||||
ValidatorAddress: response.ValidatorAddress,
|
||||
Entries: entries,
|
||||
}
|
||||
}
|
||||
|
||||
func convertRedelegationEntry(entry stakingtypes.RedelegationEntry) RedelegationEntry {
|
||||
return RedelegationEntry{
|
||||
CreationHeight: entry.CreationHeight,
|
||||
CompletionTime: entry.CompletionTime.UTC().Unix(),
|
||||
InitialBalance: entry.InitialBalance.BigInt(),
|
||||
SharesDst: entry.SharesDst.BigInt(),
|
||||
UnbondingId: entry.UnbondingId,
|
||||
UnbondingOnHoldRefCount: entry.UnbondingOnHoldRefCount,
|
||||
}
|
||||
}
|
||||
|
||||
func convertRedelegation(redelegation stakingtypes.Redelegation) Redelegation {
|
||||
entries := make([]RedelegationEntry, len(redelegation.Entries))
|
||||
for i, v := range redelegation.Entries {
|
||||
entries[i] = convertRedelegationEntry(v)
|
||||
}
|
||||
return Redelegation{
|
||||
DelegatorAddress: redelegation.DelegatorAddress,
|
||||
ValidatorSrcAddress: redelegation.ValidatorSrcAddress,
|
||||
ValidatorDstAddress: redelegation.ValidatorDstAddress,
|
||||
Entries: entries,
|
||||
}
|
||||
}
|
||||
|
||||
func convertRedelegationEntryResponse(response stakingtypes.RedelegationEntryResponse) RedelegationEntryResponse {
|
||||
return RedelegationEntryResponse{
|
||||
RedelegationEntry: convertRedelegationEntry(response.RedelegationEntry),
|
||||
Balance: response.Balance.BigInt(),
|
||||
}
|
||||
}
|
||||
|
||||
func convertRedelegationResponse(response stakingtypes.RedelegationResponse) RedelegationResponse {
|
||||
entries := make([]RedelegationEntryResponse, len(response.Entries))
|
||||
for i, v := range response.Entries {
|
||||
entries[i] = convertRedelegationEntryResponse(v)
|
||||
}
|
||||
return RedelegationResponse{
|
||||
Redelegation: convertRedelegation(response.Redelegation),
|
||||
Entries: entries,
|
||||
}
|
||||
}
|
||||
|
||||
func convertParams(params stakingtypes.Params) Params {
|
||||
return Params{
|
||||
UnbondingTime: int64(params.UnbondingTime.Seconds()),
|
||||
MaxValidators: params.MaxValidators,
|
||||
MaxEntries: params.MaxEntries,
|
||||
HistoricalEntries: params.HistoricalEntries,
|
||||
BondDenom: params.BondDenom,
|
||||
MinCommissionRate: params.MinCommissionRate.BigInt(),
|
||||
}
|
||||
}
|
||||
|
||||
func NewMsgCreateValidator(args []interface{}, sender common.Address, denom string) (*stakingtypes.MsgCreateValidator, error) {
|
||||
if len(args) != 5 {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrInvalidNumberOfArgs, 5, len(args))
|
||||
}
|
||||
description := args[0].(Description)
|
||||
commission := args[1].(CommissionRates)
|
||||
minSelfDelegation := args[2].(*big.Int)
|
||||
|
||||
pkstr := args[3].(string)
|
||||
bz, err := base64.StdEncoding.DecodeString(pkstr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pk cryptotypes.PubKey
|
||||
if len(bz) == ed25519.PubKeySize {
|
||||
pk = &ed25519.PubKey{Key: bz}
|
||||
} else {
|
||||
return nil, errors.New(ErrPubKeyInvalidLength)
|
||||
}
|
||||
pkAny, err := codectypes.NewAnyWithValue(pk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
value := args[4].(*big.Int)
|
||||
return &stakingtypes.MsgCreateValidator{
|
||||
Description: convertStakingDescription(description),
|
||||
Commission: convertStakingCommissionRates(commission),
|
||||
MinSelfDelegation: math.NewIntFromBigInt(minSelfDelegation),
|
||||
DelegatorAddress: sdk.AccAddress(sender.Bytes()).String(),
|
||||
ValidatorAddress: sdk.ValAddress(sender.Bytes()).String(),
|
||||
Pubkey: pkAny,
|
||||
Value: sdk.Coin{Denom: denom, Amount: math.NewIntFromBigInt(value)},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewMsgEditValidator(args []interface{}, sender common.Address) (*stakingtypes.MsgEditValidator, error) {
|
||||
if len(args) != 3 {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrInvalidNumberOfArgs, 3, len(args))
|
||||
}
|
||||
description := args[0].(Description)
|
||||
|
||||
commissionRateNullable := args[1].(NullableUint)
|
||||
var commissionRate *sdk.Dec
|
||||
if !commissionRateNullable.IsNull {
|
||||
value := precopmiles_common.BigIntToLegacyDec(commissionRateNullable.Value)
|
||||
commissionRate = &value
|
||||
}
|
||||
|
||||
minSelfDelegationNullable := args[2].(NullableUint)
|
||||
var minSelfDelegation *sdk.Int
|
||||
if !minSelfDelegationNullable.IsNull {
|
||||
value := math.NewIntFromBigInt(minSelfDelegationNullable.Value)
|
||||
minSelfDelegation = &value
|
||||
}
|
||||
|
||||
return &stakingtypes.MsgEditValidator{
|
||||
Description: convertStakingDescription(description),
|
||||
CommissionRate: commissionRate,
|
||||
ValidatorAddress: sdk.ValAddress(sender.Bytes()).String(),
|
||||
MinSelfDelegation: minSelfDelegation,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewMsgDelegate(args []interface{}, sender common.Address, denom string) (*stakingtypes.MsgDelegate, error) {
|
||||
if len(args) != 2 {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrInvalidNumberOfArgs, 2, len(args))
|
||||
}
|
||||
validatorAddress := args[0].(string)
|
||||
amount := args[1].(*big.Int)
|
||||
|
||||
return &stakingtypes.MsgDelegate{
|
||||
DelegatorAddress: sdk.AccAddress(sender.Bytes()).String(),
|
||||
ValidatorAddress: validatorAddress,
|
||||
Amount: sdk.Coin{Denom: denom, Amount: math.NewIntFromBigInt(amount)},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewMsgBeginRedelegate(args []interface{}, sender common.Address, denom string) (*stakingtypes.MsgBeginRedelegate, error) {
|
||||
if len(args) != 3 {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrInvalidNumberOfArgs, 3, len(args))
|
||||
}
|
||||
validatorSrcAddress := args[0].(string)
|
||||
validatorDstAddress := args[1].(string)
|
||||
amount := args[2].(*big.Int)
|
||||
|
||||
return &stakingtypes.MsgBeginRedelegate{
|
||||
DelegatorAddress: sdk.AccAddress(sender.Bytes()).String(),
|
||||
ValidatorSrcAddress: validatorSrcAddress,
|
||||
ValidatorDstAddress: validatorDstAddress,
|
||||
Amount: sdk.Coin{Denom: denom, Amount: math.NewIntFromBigInt(amount)},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewMsgUndelegate(args []interface{}, sender common.Address, denom string) (*stakingtypes.MsgUndelegate, error) {
|
||||
if len(args) != 2 {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrInvalidNumberOfArgs, 2, len(args))
|
||||
}
|
||||
validatorAddress := args[0].(string)
|
||||
amount := args[1].(*big.Int)
|
||||
|
||||
return &stakingtypes.MsgUndelegate{
|
||||
DelegatorAddress: sdk.AccAddress(sender.Bytes()).String(),
|
||||
ValidatorAddress: validatorAddress,
|
||||
Amount: sdk.Coin{Denom: denom, Amount: math.NewIntFromBigInt(amount)},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewMsgCancelUnbondingDelegation(args []interface{}, sender common.Address, denom string) (*stakingtypes.MsgCancelUnbondingDelegation, error) {
|
||||
if len(args) != 3 {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrInvalidNumberOfArgs, 3, len(args))
|
||||
}
|
||||
validatorAddress := args[0].(string)
|
||||
amount := args[1].(*big.Int)
|
||||
creationHeight := args[2].(*big.Int)
|
||||
|
||||
return &stakingtypes.MsgCancelUnbondingDelegation{
|
||||
DelegatorAddress: sdk.AccAddress(sender.Bytes()).String(),
|
||||
ValidatorAddress: validatorAddress,
|
||||
Amount: sdk.Coin{Denom: denom, Amount: math.NewIntFromBigInt(amount)},
|
||||
CreationHeight: creationHeight.Int64(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewQueryValidatorsRequest(args []interface{}) (*stakingtypes.QueryValidatorsRequest, error) {
|
||||
if len(args) != 2 {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrInvalidNumberOfArgs, 2, len(args))
|
||||
}
|
||||
status := args[0].(string)
|
||||
pagination := args[1].(PageRequest)
|
||||
|
||||
return &stakingtypes.QueryValidatorsRequest{
|
||||
Status: status,
|
||||
Pagination: convertQueryPageRequest(pagination),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewQueryValidatorRequest(args []interface{}) (*stakingtypes.QueryValidatorRequest, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrInvalidNumberOfArgs, 1, len(args))
|
||||
}
|
||||
validatorAddress := args[0].(string)
|
||||
|
||||
return &stakingtypes.QueryValidatorRequest{
|
||||
ValidatorAddr: validatorAddress,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewQueryValidatorDelegationsRequest(args []interface{}) (*stakingtypes.QueryValidatorDelegationsRequest, error) {
|
||||
if len(args) != 2 {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrInvalidNumberOfArgs, 2, len(args))
|
||||
}
|
||||
validatorAddr := args[0].(string)
|
||||
pagination := args[1].(PageRequest)
|
||||
|
||||
return &stakingtypes.QueryValidatorDelegationsRequest{
|
||||
ValidatorAddr: validatorAddr,
|
||||
Pagination: convertQueryPageRequest(pagination),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewQueryValidatorUnbondingDelegationsRequest(args []interface{}) (*stakingtypes.QueryValidatorUnbondingDelegationsRequest, error) {
|
||||
if len(args) != 2 {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrInvalidNumberOfArgs, 2, len(args))
|
||||
}
|
||||
validatorAddr := args[0].(string)
|
||||
pagination := args[1].(PageRequest)
|
||||
|
||||
return &stakingtypes.QueryValidatorUnbondingDelegationsRequest{
|
||||
ValidatorAddr: validatorAddr,
|
||||
Pagination: convertQueryPageRequest(pagination),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewQueryDelegationRequest(args []interface{}) (*stakingtypes.QueryDelegationRequest, error) {
|
||||
if len(args) != 2 {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrInvalidNumberOfArgs, 2, len(args))
|
||||
}
|
||||
delegatorAddr := args[0].(string)
|
||||
validatorAddr := args[1].(string)
|
||||
|
||||
return &stakingtypes.QueryDelegationRequest{
|
||||
DelegatorAddr: delegatorAddr,
|
||||
ValidatorAddr: validatorAddr,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewQueryUnbondingDelegationRequest(args []interface{}) (*stakingtypes.QueryUnbondingDelegationRequest, error) {
|
||||
if len(args) != 2 {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrInvalidNumberOfArgs, 2, len(args))
|
||||
}
|
||||
delegatorAddr := args[0].(string)
|
||||
validatorAddr := args[1].(string)
|
||||
|
||||
return &stakingtypes.QueryUnbondingDelegationRequest{
|
||||
DelegatorAddr: delegatorAddr,
|
||||
ValidatorAddr: validatorAddr,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewQueryDelegatorDelegationsRequest(args []interface{}) (*stakingtypes.QueryDelegatorDelegationsRequest, error) {
|
||||
if len(args) != 2 {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrInvalidNumberOfArgs, 2, len(args))
|
||||
}
|
||||
delegatorAddr := args[0].(string)
|
||||
pagination := args[1].(PageRequest)
|
||||
|
||||
return &stakingtypes.QueryDelegatorDelegationsRequest{
|
||||
DelegatorAddr: delegatorAddr,
|
||||
Pagination: convertQueryPageRequest(pagination),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewQueryDelegatorUnbondingDelegationsRequest(args []interface{}) (*stakingtypes.QueryDelegatorUnbondingDelegationsRequest, error) {
|
||||
if len(args) != 2 {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrInvalidNumberOfArgs, 2, len(args))
|
||||
}
|
||||
delegatorAddr := args[0].(string)
|
||||
pagination := args[1].(PageRequest)
|
||||
|
||||
return &stakingtypes.QueryDelegatorUnbondingDelegationsRequest{
|
||||
DelegatorAddr: delegatorAddr,
|
||||
Pagination: convertQueryPageRequest(pagination),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewQueryRedelegationsRequest(args []interface{}) (*stakingtypes.QueryRedelegationsRequest, error) {
|
||||
if len(args) != 4 {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrInvalidNumberOfArgs, 4, len(args))
|
||||
}
|
||||
delegatorAddress := args[0].(string)
|
||||
validatorSrcAddress := args[1].(string)
|
||||
validatorDstAddress := args[2].(string)
|
||||
pagination := args[3].(PageRequest)
|
||||
|
||||
return &stakingtypes.QueryRedelegationsRequest{
|
||||
DelegatorAddr: delegatorAddress,
|
||||
SrcValidatorAddr: validatorSrcAddress,
|
||||
DstValidatorAddr: validatorDstAddress,
|
||||
Pagination: convertQueryPageRequest(pagination),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewQueryDelegatorValidatorsRequest(args []interface{}) (*stakingtypes.QueryDelegatorValidatorsRequest, error) {
|
||||
if len(args) != 2 {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrInvalidNumberOfArgs, 2, len(args))
|
||||
}
|
||||
delegatorAddr := args[0].(string)
|
||||
pagination := args[1].(PageRequest)
|
||||
|
||||
return &stakingtypes.QueryDelegatorValidatorsRequest{
|
||||
DelegatorAddr: delegatorAddr,
|
||||
Pagination: convertQueryPageRequest(pagination),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewQueryDelegatorValidatorRequest(args []interface{}) (*stakingtypes.QueryDelegatorValidatorRequest, error) {
|
||||
if len(args) != 2 {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrInvalidNumberOfArgs, 2, len(args))
|
||||
}
|
||||
delegatorAddr := args[0].(string)
|
||||
validatorAddr := args[1].(string)
|
||||
|
||||
return &stakingtypes.QueryDelegatorValidatorRequest{
|
||||
DelegatorAddr: delegatorAddr,
|
||||
ValidatorAddr: validatorAddr,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewQueryPoolRequest(args []interface{}) (*stakingtypes.QueryPoolRequest, error) {
|
||||
if len(args) != 0 {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrInvalidNumberOfArgs, 0, len(args))
|
||||
}
|
||||
|
||||
return &stakingtypes.QueryPoolRequest{}, nil
|
||||
}
|
||||
|
||||
func NewQueryParamsRequest(args []interface{}) (*stakingtypes.QueryParamsRequest, error) {
|
||||
if len(args) != 0 {
|
||||
return nil, fmt.Errorf(precopmiles_common.ErrInvalidNumberOfArgs, 0, len(args))
|
||||
}
|
||||
|
||||
return &stakingtypes.QueryParamsRequest{}, nil
|
||||
}
|
@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/0glabs/0g-chain/app"
|
||||
"github.com/0glabs/0g-chain/chaincfg"
|
||||
dasignersprecompile "github.com/0glabs/0g-chain/precompiles/dasigners"
|
||||
precopmiles_common "github.com/0glabs/0g-chain/precompiles/common"
|
||||
"github.com/0glabs/0g-chain/x/bep3/types"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
@ -51,7 +51,7 @@ func GenSigner() *TestSigner {
|
||||
addr, priv := emtests.NewAddrKey()
|
||||
s.PrivKey = priv
|
||||
s.Addr = addr
|
||||
s.HexAddr = dasignersprecompile.ToLowerHexWithoutPrefix(s.Addr)
|
||||
s.HexAddr = precopmiles_common.ToLowerHexWithoutPrefix(s.Addr)
|
||||
s.Signer = emtests.NewSigner(priv)
|
||||
return &s
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user