mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-11-04 09:17:28 +00:00 
			
		
		
		
	Merge pull request #84 from 0glabs/staking-precompile
feat: staking precompile
This commit is contained in:
		
						commit
						76eebc57c1
					
				
							
								
								
									
										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
 | 
			
		||||
							
								
								
									
										10
									
								
								app/app.go
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								app/app.go
									
									
									
									
									
								
							@ -110,6 +110,7 @@ import (
 | 
			
		||||
	chainparams "github.com/0glabs/0g-chain/app/params"
 | 
			
		||||
	"github.com/0glabs/0g-chain/chaincfg"
 | 
			
		||||
	dasignersprecompile "github.com/0glabs/0g-chain/precompiles/dasigners"
 | 
			
		||||
	stakingprecompile "github.com/0glabs/0g-chain/precompiles/staking"
 | 
			
		||||
 | 
			
		||||
	"github.com/0glabs/0g-chain/x/bep3"
 | 
			
		||||
	bep3keeper "github.com/0glabs/0g-chain/x/bep3/keeper"
 | 
			
		||||
@ -499,11 +500,18 @@ func NewApp(
 | 
			
		||||
	app.dasignersKeeper = dasignerskeeper.NewKeeper(keys[dasignerstypes.StoreKey], appCodec, app.stakingKeeper, govAuthAddrStr)
 | 
			
		||||
	// precopmiles
 | 
			
		||||
	precompiles := make(map[common.Address]vm.PrecompiledContract)
 | 
			
		||||
	// dasigners
 | 
			
		||||
	daSignersPrecompile, err := dasignersprecompile.NewDASignersPrecompile(app.dasignersKeeper)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic("initialize precompile failed")
 | 
			
		||||
		panic(fmt.Sprintf("initialize dasigners precompile failed: %v", err))
 | 
			
		||||
	}
 | 
			
		||||
	precompiles[daSignersPrecompile.Address()] = daSignersPrecompile
 | 
			
		||||
	// staking
 | 
			
		||||
	stakingPrecompile, err := stakingprecompile.NewStakingPrecompile(app.stakingKeeper)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(fmt.Sprintf("initialize staking precompile failed: %v", err))
 | 
			
		||||
	}
 | 
			
		||||
	precompiles[stakingPrecompile.Address()] = stakingPrecompile
 | 
			
		||||
 | 
			
		||||
	app.evmKeeper = evmkeeper.NewKeeper(
 | 
			
		||||
		appCodec, keys[evmtypes.StoreKey], tkeys[evmtypes.TransientKey],
 | 
			
		||||
 | 
			
		||||
@ -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 {
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,7 @@ import (
 | 
			
		||||
	"github.com/0glabs/0g-chain/x/dasigners/v1/types"
 | 
			
		||||
	abci "github.com/cometbft/cometbft/abci/types"
 | 
			
		||||
	"github.com/consensys/gnark-crypto/ecc/bn254"
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
 | 
			
		||||
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
			
		||||
	"github.com/ethereum/go-ethereum/accounts/abi"
 | 
			
		||||
	"github.com/ethereum/go-ethereum/common"
 | 
			
		||||
@ -23,7 +24,6 @@ import (
 | 
			
		||||
	"cosmossdk.io/math"
 | 
			
		||||
	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
 | 
			
		||||
	"github.com/ethereum/go-ethereum/core/vm"
 | 
			
		||||
	"github.com/evmos/ethermint/crypto/ethsecp256k1"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type DASignersTestSuite struct {
 | 
			
		||||
@ -44,8 +44,7 @@ func (suite *DASignersTestSuite) AddDelegation(from string, to string, amount ma
 | 
			
		||||
	suite.Require().NoError(err)
 | 
			
		||||
	validator, found := suite.StakingKeeper.GetValidator(suite.Ctx, valAddr)
 | 
			
		||||
	if !found {
 | 
			
		||||
		consPriv, err := ethsecp256k1.GenerateKey()
 | 
			
		||||
		suite.Require().NoError(err)
 | 
			
		||||
		consPriv := ed25519.GenPrivKey()
 | 
			
		||||
		newValidator, err := stakingtypes.NewValidator(valAddr, consPriv.PubKey(), stakingtypes.Description{})
 | 
			
		||||
		suite.Require().NoError(err)
 | 
			
		||||
		validator = newValidator
 | 
			
		||||
@ -73,8 +72,8 @@ func (suite *DASignersTestSuite) SetupTest() {
 | 
			
		||||
	suite.Assert().EqualValues(ok, true)
 | 
			
		||||
	suite.dasigners = precompile.(*dasignersprecompile.DASignersPrecompile)
 | 
			
		||||
 | 
			
		||||
	suite.signerOne = testutil.GenSigner()
 | 
			
		||||
	suite.signerTwo = testutil.GenSigner()
 | 
			
		||||
	suite.signerOne = suite.GenSigner()
 | 
			
		||||
	suite.signerTwo = suite.GenSigner()
 | 
			
		||||
	abi, err := abi.JSON(strings.NewReader(dasignersprecompile.DASignersABI))
 | 
			
		||||
	suite.Assert().NoError(err)
 | 
			
		||||
	suite.abi = abi
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										415
									
								
								precompiles/interfaces/contracts/IStaking.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										415
									
								
								precompiles/interfaces/contracts/IStaking.sol
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,415 @@
 | 
			
		||||
// 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, // 0gchaind tendermint show-validator
 | 
			
		||||
        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;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @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: "istanbul",
 | 
			
		||||
                    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
											
										
									
								
							
							
								
								
									
										1716
									
								
								precompiles/staking/IStaking.abi
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1716
									
								
								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))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										801
									
								
								precompiles/staking/query_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										801
									
								
								precompiles/staking/query_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,801 @@
 | 
			
		||||
package staking_test
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"math/big"
 | 
			
		||||
 | 
			
		||||
	stakingprecompile "github.com/0glabs/0g-chain/precompiles/staking"
 | 
			
		||||
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
			
		||||
	query "github.com/cosmos/cosmos-sdk/types/query"
 | 
			
		||||
	"github.com/ethereum/go-ethereum/common"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (s *StakingTestSuite) TestValidators() {
 | 
			
		||||
	method := stakingprecompile.StakingFunctionValidators
 | 
			
		||||
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name        string
 | 
			
		||||
		malleate    func() []byte
 | 
			
		||||
		postCheck   func(bz []byte)
 | 
			
		||||
		gas         uint64
 | 
			
		||||
		expErr      bool
 | 
			
		||||
		errContains string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			"success",
 | 
			
		||||
			func() []byte {
 | 
			
		||||
				input, err := s.abi.Pack(
 | 
			
		||||
					method,
 | 
			
		||||
					"",
 | 
			
		||||
					query.PageRequest{
 | 
			
		||||
						Limit:      10,
 | 
			
		||||
						CountTotal: true,
 | 
			
		||||
					},
 | 
			
		||||
				)
 | 
			
		||||
				s.Assert().NoError(err)
 | 
			
		||||
				return input
 | 
			
		||||
			},
 | 
			
		||||
			func(data []byte) {
 | 
			
		||||
				out, err := s.abi.Methods[method].Outputs.Unpack(data)
 | 
			
		||||
				s.Require().NoError(err, "failed to unpack output")
 | 
			
		||||
				validators := out[0].([]stakingprecompile.Validator)
 | 
			
		||||
				paginationResult := out[1].(stakingprecompile.PageResponse)
 | 
			
		||||
				s.Assert().EqualValues(3, len(validators))
 | 
			
		||||
				s.Assert().EqualValues(3, paginationResult.Total)
 | 
			
		||||
			},
 | 
			
		||||
			100000,
 | 
			
		||||
			false,
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		s.Run(tc.name, func() {
 | 
			
		||||
			s.SetupTest()
 | 
			
		||||
			s.AddDelegation(s.signerOne.HexAddr, s.signerTwo.HexAddr, sdk.NewIntFromUint64(1000000))
 | 
			
		||||
 | 
			
		||||
			bz, err := s.runTx(tc.malleate(), s.signerOne, 10000000)
 | 
			
		||||
 | 
			
		||||
			if tc.expErr {
 | 
			
		||||
				s.Require().Error(err)
 | 
			
		||||
				s.Require().Contains(err.Error(), tc.errContains)
 | 
			
		||||
			} else {
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
				s.Require().NotNil(bz)
 | 
			
		||||
				tc.postCheck(bz)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *StakingTestSuite) TestValidator() {
 | 
			
		||||
	method := stakingprecompile.StakingFunctionValidator
 | 
			
		||||
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name        string
 | 
			
		||||
		malleate    func(operatorAddress string) []byte
 | 
			
		||||
		postCheck   func(bz []byte)
 | 
			
		||||
		gas         uint64
 | 
			
		||||
		expErr      bool
 | 
			
		||||
		errContains string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			"success",
 | 
			
		||||
			func(operatorAddress string) []byte {
 | 
			
		||||
				input, err := s.abi.Pack(
 | 
			
		||||
					method,
 | 
			
		||||
					operatorAddress,
 | 
			
		||||
				)
 | 
			
		||||
				s.Assert().NoError(err)
 | 
			
		||||
				return input
 | 
			
		||||
			},
 | 
			
		||||
			func(data []byte) {
 | 
			
		||||
				out, err := s.abi.Methods[method].Outputs.Unpack(data)
 | 
			
		||||
				s.Require().NoError(err, "failed to unpack output")
 | 
			
		||||
				operatorAddress, err := s.firstBondedValidator()
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
				validator := out[0].(stakingprecompile.Validator)
 | 
			
		||||
				s.Require().EqualValues(common.HexToAddress(validator.OperatorAddress), common.BytesToAddress(operatorAddress.Bytes()))
 | 
			
		||||
			},
 | 
			
		||||
			100000,
 | 
			
		||||
			false,
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		s.Run(tc.name, func() {
 | 
			
		||||
			s.SetupTest()
 | 
			
		||||
			operatorAddress, err := s.firstBondedValidator()
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
 | 
			
		||||
			bz, err := s.runTx(tc.malleate(operatorAddress.String()), s.signerOne, 10000000)
 | 
			
		||||
 | 
			
		||||
			if tc.expErr {
 | 
			
		||||
				s.Require().Error(err)
 | 
			
		||||
				s.Require().Contains(err.Error(), tc.errContains)
 | 
			
		||||
			} else {
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
				s.Require().NotNil(bz)
 | 
			
		||||
				tc.postCheck(bz)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *StakingTestSuite) TestValidatorDelegations() {
 | 
			
		||||
	method := stakingprecompile.StakingFunctionValidatorDelegations
 | 
			
		||||
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name        string
 | 
			
		||||
		malleate    func(operatorAddress string) []byte
 | 
			
		||||
		postCheck   func(bz []byte)
 | 
			
		||||
		gas         uint64
 | 
			
		||||
		expErr      bool
 | 
			
		||||
		errContains string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			"success",
 | 
			
		||||
			func(operatorAddress string) []byte {
 | 
			
		||||
				input, err := s.abi.Pack(
 | 
			
		||||
					method,
 | 
			
		||||
					operatorAddress,
 | 
			
		||||
					query.PageRequest{
 | 
			
		||||
						Limit:      10,
 | 
			
		||||
						CountTotal: true,
 | 
			
		||||
					},
 | 
			
		||||
				)
 | 
			
		||||
				s.Assert().NoError(err)
 | 
			
		||||
				return input
 | 
			
		||||
			},
 | 
			
		||||
			func(data []byte) {
 | 
			
		||||
				out, err := s.abi.Methods[method].Outputs.Unpack(data)
 | 
			
		||||
				s.Require().NoError(err, "failed to unpack output")
 | 
			
		||||
				operatorAddress, err := s.firstBondedValidator()
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
				delegations := out[0].([]stakingprecompile.DelegationResponse)
 | 
			
		||||
				d := s.stakingKeeper.GetValidatorDelegations(s.Ctx, operatorAddress)
 | 
			
		||||
				s.Require().EqualValues(len(delegations), len(d))
 | 
			
		||||
				// jsonData, _ := json.MarshalIndent(delegations, "", "    ")
 | 
			
		||||
				// fmt.Printf("delegations: %s\n", string(jsonData))
 | 
			
		||||
			},
 | 
			
		||||
			100000,
 | 
			
		||||
			false,
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		s.Run(tc.name, func() {
 | 
			
		||||
			s.SetupTest()
 | 
			
		||||
			operatorAddress, err := s.firstBondedValidator()
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
 | 
			
		||||
			bz, err := s.runTx(tc.malleate(operatorAddress.String()), s.signerOne, 10000000)
 | 
			
		||||
 | 
			
		||||
			if tc.expErr {
 | 
			
		||||
				s.Require().Error(err)
 | 
			
		||||
				s.Require().Contains(err.Error(), tc.errContains)
 | 
			
		||||
			} else {
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
				s.Require().NotNil(bz)
 | 
			
		||||
				tc.postCheck(bz)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *StakingTestSuite) TestValidatorUnbondingDelegations() {
 | 
			
		||||
	method := stakingprecompile.StakingFunctionValidatorUnbondingDelegations
 | 
			
		||||
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name        string
 | 
			
		||||
		malleate    func(operatorAddress string) []byte
 | 
			
		||||
		postCheck   func(bz []byte)
 | 
			
		||||
		gas         uint64
 | 
			
		||||
		expErr      bool
 | 
			
		||||
		errContains string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			"success",
 | 
			
		||||
			func(operatorAddress string) []byte {
 | 
			
		||||
				input, err := s.abi.Pack(
 | 
			
		||||
					method,
 | 
			
		||||
					operatorAddress,
 | 
			
		||||
					query.PageRequest{
 | 
			
		||||
						Limit:      10,
 | 
			
		||||
						CountTotal: true,
 | 
			
		||||
					},
 | 
			
		||||
				)
 | 
			
		||||
				s.Assert().NoError(err)
 | 
			
		||||
				return input
 | 
			
		||||
			},
 | 
			
		||||
			func(data []byte) {
 | 
			
		||||
				out, err := s.abi.Methods[method].Outputs.Unpack(data)
 | 
			
		||||
				s.Require().NoError(err, "failed to unpack output")
 | 
			
		||||
				unbonding := out[0].([]stakingprecompile.UnbondingDelegation)
 | 
			
		||||
				s.Require().EqualValues(len(unbonding), 1)
 | 
			
		||||
				// jsonData, _ := json.MarshalIndent(unbonding, "", "    ")
 | 
			
		||||
				// fmt.Printf("delegations: %s\n", string(jsonData))
 | 
			
		||||
			},
 | 
			
		||||
			100000,
 | 
			
		||||
			false,
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		s.Run(tc.name, func() {
 | 
			
		||||
			s.SetupTest()
 | 
			
		||||
			operatorAddress, err := s.firstBondedValidator()
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
			d := s.stakingKeeper.GetValidatorDelegations(s.Ctx, operatorAddress)
 | 
			
		||||
			delAddr, err := sdk.AccAddressFromBech32(d[0].DelegatorAddress)
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
			_, err = s.stakingKeeper.Undelegate(s.Ctx, delAddr, operatorAddress, sdk.NewDec(1))
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
 | 
			
		||||
			bz, err := s.runTx(tc.malleate(operatorAddress.String()), s.signerOne, 10000000)
 | 
			
		||||
 | 
			
		||||
			if tc.expErr {
 | 
			
		||||
				s.Require().Error(err)
 | 
			
		||||
				s.Require().Contains(err.Error(), tc.errContains)
 | 
			
		||||
			} else {
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
				s.Require().NotNil(bz)
 | 
			
		||||
				tc.postCheck(bz)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *StakingTestSuite) TestDelegation() {
 | 
			
		||||
	method := stakingprecompile.StakingFunctionDelegation
 | 
			
		||||
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name        string
 | 
			
		||||
		malleate    func(delAddr, valAddr string) []byte
 | 
			
		||||
		postCheck   func(bz []byte)
 | 
			
		||||
		gas         uint64
 | 
			
		||||
		expErr      bool
 | 
			
		||||
		errContains string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			"success",
 | 
			
		||||
			func(delAddr, valAddr string) []byte {
 | 
			
		||||
				input, err := s.abi.Pack(
 | 
			
		||||
					method,
 | 
			
		||||
					delAddr,
 | 
			
		||||
					valAddr,
 | 
			
		||||
				)
 | 
			
		||||
				s.Assert().NoError(err)
 | 
			
		||||
				return input
 | 
			
		||||
			},
 | 
			
		||||
			func(data []byte) {
 | 
			
		||||
				out, err := s.abi.Methods[method].Outputs.Unpack(data)
 | 
			
		||||
				s.Require().NoError(err, "failed to unpack output")
 | 
			
		||||
				d := out[0].(stakingprecompile.Delegation)
 | 
			
		||||
				b := out[1].(*big.Int)
 | 
			
		||||
				_ = d
 | 
			
		||||
				_ = b
 | 
			
		||||
				/*
 | 
			
		||||
					jsonData, _ := json.MarshalIndent(d, "", "    ")
 | 
			
		||||
					fmt.Printf("delegation: %s\n", string(jsonData))
 | 
			
		||||
					fmt.Printf("balance: %v\n", b)
 | 
			
		||||
				*/
 | 
			
		||||
			},
 | 
			
		||||
			100000,
 | 
			
		||||
			false,
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		s.Run(tc.name, func() {
 | 
			
		||||
			s.SetupTest()
 | 
			
		||||
			operatorAddress, err := s.firstBondedValidator()
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
			d := s.stakingKeeper.GetValidatorDelegations(s.Ctx, operatorAddress)
 | 
			
		||||
			delAddr, err := sdk.AccAddressFromBech32(d[0].DelegatorAddress)
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
 | 
			
		||||
			bz, err := s.runTx(tc.malleate(delAddr.String(), operatorAddress.String()), s.signerOne, 10000000)
 | 
			
		||||
 | 
			
		||||
			if tc.expErr {
 | 
			
		||||
				s.Require().Error(err)
 | 
			
		||||
				s.Require().Contains(err.Error(), tc.errContains)
 | 
			
		||||
			} else {
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
				s.Require().NotNil(bz)
 | 
			
		||||
				tc.postCheck(bz)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *StakingTestSuite) TestUnbondingDelegation() {
 | 
			
		||||
	method := stakingprecompile.StakingFunctionUnbondingDelegation
 | 
			
		||||
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name        string
 | 
			
		||||
		malleate    func(delAddr, valAddr string) []byte
 | 
			
		||||
		postCheck   func(bz []byte)
 | 
			
		||||
		gas         uint64
 | 
			
		||||
		expErr      bool
 | 
			
		||||
		errContains string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			"success",
 | 
			
		||||
			func(delAddr, valAddr string) []byte {
 | 
			
		||||
				input, err := s.abi.Pack(
 | 
			
		||||
					method,
 | 
			
		||||
					delAddr,
 | 
			
		||||
					valAddr,
 | 
			
		||||
				)
 | 
			
		||||
				s.Assert().NoError(err)
 | 
			
		||||
				return input
 | 
			
		||||
			},
 | 
			
		||||
			func(data []byte) {
 | 
			
		||||
				out, err := s.abi.Methods[method].Outputs.Unpack(data)
 | 
			
		||||
				s.Require().NoError(err, "failed to unpack output")
 | 
			
		||||
				u := out[0].(stakingprecompile.UnbondingDelegation)
 | 
			
		||||
				_ = u
 | 
			
		||||
				// jsonData, _ := json.MarshalIndent(u, "", "    ")
 | 
			
		||||
				// fmt.Printf("delegation: %s\n", string(jsonData))
 | 
			
		||||
			},
 | 
			
		||||
			100000,
 | 
			
		||||
			false,
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		s.Run(tc.name, func() {
 | 
			
		||||
			s.SetupTest()
 | 
			
		||||
			operatorAddress, err := s.firstBondedValidator()
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
			d := s.stakingKeeper.GetValidatorDelegations(s.Ctx, operatorAddress)
 | 
			
		||||
			delAddr, err := sdk.AccAddressFromBech32(d[0].DelegatorAddress)
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
			_, err = s.stakingKeeper.Undelegate(s.Ctx, delAddr, operatorAddress, sdk.NewDec(1))
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
 | 
			
		||||
			bz, err := s.runTx(tc.malleate(delAddr.String(), operatorAddress.String()), s.signerOne, 10000000)
 | 
			
		||||
 | 
			
		||||
			if tc.expErr {
 | 
			
		||||
				s.Require().Error(err)
 | 
			
		||||
				s.Require().Contains(err.Error(), tc.errContains)
 | 
			
		||||
			} else {
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
				s.Require().NotNil(bz)
 | 
			
		||||
				tc.postCheck(bz)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *StakingTestSuite) TestDelegatorDelegations() {
 | 
			
		||||
	method := stakingprecompile.StakingFunctionDelegatorDelegations
 | 
			
		||||
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name        string
 | 
			
		||||
		malleate    func(delAddr string) []byte
 | 
			
		||||
		postCheck   func(bz []byte)
 | 
			
		||||
		gas         uint64
 | 
			
		||||
		expErr      bool
 | 
			
		||||
		errContains string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			"success",
 | 
			
		||||
			func(delAddr string) []byte {
 | 
			
		||||
				input, err := s.abi.Pack(
 | 
			
		||||
					method,
 | 
			
		||||
					delAddr,
 | 
			
		||||
					query.PageRequest{
 | 
			
		||||
						Limit:      10,
 | 
			
		||||
						CountTotal: true,
 | 
			
		||||
					},
 | 
			
		||||
				)
 | 
			
		||||
				s.Assert().NoError(err)
 | 
			
		||||
				return input
 | 
			
		||||
			},
 | 
			
		||||
			func(data []byte) {
 | 
			
		||||
				out, err := s.abi.Methods[method].Outputs.Unpack(data)
 | 
			
		||||
				s.Require().NoError(err, "failed to unpack output")
 | 
			
		||||
				d := out[0].([]stakingprecompile.DelegationResponse)
 | 
			
		||||
				paginationResult := out[1].(stakingprecompile.PageResponse)
 | 
			
		||||
				s.Assert().EqualValues(1, len(d))
 | 
			
		||||
				s.Assert().EqualValues(1, paginationResult.Total)
 | 
			
		||||
				// jsonData, _ := json.MarshalIndent(d, "", "    ")
 | 
			
		||||
				// fmt.Printf("delegation: %s\n", string(jsonData))
 | 
			
		||||
			},
 | 
			
		||||
			100000,
 | 
			
		||||
			false,
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		s.Run(tc.name, func() {
 | 
			
		||||
			s.SetupTest()
 | 
			
		||||
			operatorAddress, err := s.firstBondedValidator()
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
			d := s.stakingKeeper.GetValidatorDelegations(s.Ctx, operatorAddress)
 | 
			
		||||
			delAddr, err := sdk.AccAddressFromBech32(d[0].DelegatorAddress)
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
 | 
			
		||||
			bz, err := s.runTx(tc.malleate(delAddr.String()), s.signerOne, 10000000)
 | 
			
		||||
 | 
			
		||||
			if tc.expErr {
 | 
			
		||||
				s.Require().Error(err)
 | 
			
		||||
				s.Require().Contains(err.Error(), tc.errContains)
 | 
			
		||||
			} else {
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
				s.Require().NotNil(bz)
 | 
			
		||||
				tc.postCheck(bz)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *StakingTestSuite) TestDelegatorUnbondingDelegations() {
 | 
			
		||||
	method := stakingprecompile.StakingFunctionDelegatorUnbondingDelegations
 | 
			
		||||
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name        string
 | 
			
		||||
		malleate    func(delAddr string) []byte
 | 
			
		||||
		postCheck   func(bz []byte)
 | 
			
		||||
		gas         uint64
 | 
			
		||||
		expErr      bool
 | 
			
		||||
		errContains string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			"success",
 | 
			
		||||
			func(delAddr string) []byte {
 | 
			
		||||
				input, err := s.abi.Pack(
 | 
			
		||||
					method,
 | 
			
		||||
					delAddr,
 | 
			
		||||
					query.PageRequest{
 | 
			
		||||
						Limit:      10,
 | 
			
		||||
						CountTotal: true,
 | 
			
		||||
					},
 | 
			
		||||
				)
 | 
			
		||||
				s.Assert().NoError(err)
 | 
			
		||||
				return input
 | 
			
		||||
			},
 | 
			
		||||
			func(data []byte) {
 | 
			
		||||
				out, err := s.abi.Methods[method].Outputs.Unpack(data)
 | 
			
		||||
				s.Require().NoError(err, "failed to unpack output")
 | 
			
		||||
				d := out[0].([]stakingprecompile.UnbondingDelegation)
 | 
			
		||||
				paginationResult := out[1].(stakingprecompile.PageResponse)
 | 
			
		||||
				s.Assert().EqualValues(1, len(d))
 | 
			
		||||
				s.Assert().EqualValues(1, paginationResult.Total)
 | 
			
		||||
				// jsonData, _ := json.MarshalIndent(d, "", "    ")
 | 
			
		||||
				// fmt.Printf("delegation: %s\n", string(jsonData))
 | 
			
		||||
			},
 | 
			
		||||
			100000,
 | 
			
		||||
			false,
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		s.Run(tc.name, func() {
 | 
			
		||||
			s.SetupTest()
 | 
			
		||||
			operatorAddress, err := s.firstBondedValidator()
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
			d := s.stakingKeeper.GetValidatorDelegations(s.Ctx, operatorAddress)
 | 
			
		||||
			delAddr, err := sdk.AccAddressFromBech32(d[0].DelegatorAddress)
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
			_, err = s.stakingKeeper.Undelegate(s.Ctx, delAddr, operatorAddress, sdk.NewDec(1))
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
 | 
			
		||||
			bz, err := s.runTx(tc.malleate(delAddr.String()), s.signerOne, 10000000)
 | 
			
		||||
 | 
			
		||||
			if tc.expErr {
 | 
			
		||||
				s.Require().Error(err)
 | 
			
		||||
				s.Require().Contains(err.Error(), tc.errContains)
 | 
			
		||||
			} else {
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
				s.Require().NotNil(bz)
 | 
			
		||||
				tc.postCheck(bz)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *StakingTestSuite) TestRedelegations() {
 | 
			
		||||
	method := stakingprecompile.StakingFunctionRedelegations
 | 
			
		||||
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name        string
 | 
			
		||||
		malleate    func(delAddr, srcValAddr, dstValAddr string) []byte
 | 
			
		||||
		postCheck   func(bz []byte)
 | 
			
		||||
		gas         uint64
 | 
			
		||||
		expErr      bool
 | 
			
		||||
		errContains string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			"success",
 | 
			
		||||
			func(delAddr, srcValAddr, dstValAddr string) []byte {
 | 
			
		||||
				input, err := s.abi.Pack(
 | 
			
		||||
					method,
 | 
			
		||||
					delAddr,
 | 
			
		||||
					srcValAddr,
 | 
			
		||||
					dstValAddr,
 | 
			
		||||
					query.PageRequest{
 | 
			
		||||
						Limit:      10,
 | 
			
		||||
						CountTotal: true,
 | 
			
		||||
					},
 | 
			
		||||
				)
 | 
			
		||||
				s.Assert().NoError(err)
 | 
			
		||||
				return input
 | 
			
		||||
			},
 | 
			
		||||
			func(data []byte) {
 | 
			
		||||
				out, err := s.abi.Methods[method].Outputs.Unpack(data)
 | 
			
		||||
				s.Require().NoError(err, "failed to unpack output")
 | 
			
		||||
				d := out[0].([]stakingprecompile.RedelegationResponse)
 | 
			
		||||
				paginationResult := out[1].(stakingprecompile.PageResponse)
 | 
			
		||||
				s.Assert().EqualValues(1, len(d))
 | 
			
		||||
				s.Assert().EqualValues(1, paginationResult.Total)
 | 
			
		||||
				// jsonData, _ := json.MarshalIndent(d, "", "    ")
 | 
			
		||||
				// fmt.Printf("redelegations: %s\n", string(jsonData))
 | 
			
		||||
			},
 | 
			
		||||
			100000,
 | 
			
		||||
			false,
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		s.Run(tc.name, func() {
 | 
			
		||||
			s.SetupTest()
 | 
			
		||||
			operatorAddress, err := s.firstBondedValidator()
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
			d := s.stakingKeeper.GetValidatorDelegations(s.Ctx, operatorAddress)
 | 
			
		||||
			delAddr, err := sdk.AccAddressFromBech32(d[0].DelegatorAddress)
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
			// setup redelegations
 | 
			
		||||
			s.setupValidator(s.signerOne)
 | 
			
		||||
			_, err = s.stakingKeeper.BeginRedelegation(s.Ctx, delAddr, operatorAddress, s.signerOne.ValAddr, sdk.NewDec(1))
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
 | 
			
		||||
			bz, err := s.runTx(tc.malleate(delAddr.String(), operatorAddress.String(), s.signerOne.ValAddr.String()), s.signerOne, 10000000)
 | 
			
		||||
 | 
			
		||||
			if tc.expErr {
 | 
			
		||||
				s.Require().Error(err)
 | 
			
		||||
				s.Require().Contains(err.Error(), tc.errContains)
 | 
			
		||||
			} else {
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
				s.Require().NotNil(bz)
 | 
			
		||||
				tc.postCheck(bz)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *StakingTestSuite) TestDelegatorValidators() {
 | 
			
		||||
	method := stakingprecompile.StakingFunctionDelegatorValidators
 | 
			
		||||
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name        string
 | 
			
		||||
		malleate    func(delAddr string) []byte
 | 
			
		||||
		postCheck   func(bz []byte)
 | 
			
		||||
		gas         uint64
 | 
			
		||||
		expErr      bool
 | 
			
		||||
		errContains string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			"success",
 | 
			
		||||
			func(delAddr string) []byte {
 | 
			
		||||
				input, err := s.abi.Pack(
 | 
			
		||||
					method,
 | 
			
		||||
					delAddr,
 | 
			
		||||
					query.PageRequest{
 | 
			
		||||
						Limit:      10,
 | 
			
		||||
						CountTotal: true,
 | 
			
		||||
					},
 | 
			
		||||
				)
 | 
			
		||||
				s.Assert().NoError(err)
 | 
			
		||||
				return input
 | 
			
		||||
			},
 | 
			
		||||
			func(data []byte) {
 | 
			
		||||
				out, err := s.abi.Methods[method].Outputs.Unpack(data)
 | 
			
		||||
				s.Require().NoError(err, "failed to unpack output")
 | 
			
		||||
				v := out[0].([]stakingprecompile.Validator)
 | 
			
		||||
				paginationResult := out[1].(stakingprecompile.PageResponse)
 | 
			
		||||
				s.Assert().EqualValues(1, len(v))
 | 
			
		||||
				s.Assert().EqualValues(1, paginationResult.Total)
 | 
			
		||||
				// jsonData, _ := json.MarshalIndent(v, "", "    ")
 | 
			
		||||
				// fmt.Printf("validators: %s\n", string(jsonData))
 | 
			
		||||
			},
 | 
			
		||||
			100000,
 | 
			
		||||
			false,
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		s.Run(tc.name, func() {
 | 
			
		||||
			s.SetupTest()
 | 
			
		||||
			operatorAddress, err := s.firstBondedValidator()
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
			d := s.stakingKeeper.GetValidatorDelegations(s.Ctx, operatorAddress)
 | 
			
		||||
			delAddr, err := sdk.AccAddressFromBech32(d[0].DelegatorAddress)
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
 | 
			
		||||
			bz, err := s.runTx(tc.malleate(delAddr.String()), s.signerOne, 10000000)
 | 
			
		||||
 | 
			
		||||
			if tc.expErr {
 | 
			
		||||
				s.Require().Error(err)
 | 
			
		||||
				s.Require().Contains(err.Error(), tc.errContains)
 | 
			
		||||
			} else {
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
				s.Require().NotNil(bz)
 | 
			
		||||
				tc.postCheck(bz)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *StakingTestSuite) TestDelegatorValidator() {
 | 
			
		||||
	method := stakingprecompile.StakingFunctionDelegatorValidator
 | 
			
		||||
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name        string
 | 
			
		||||
		malleate    func(delAddr, valAddr string) []byte
 | 
			
		||||
		postCheck   func(bz []byte)
 | 
			
		||||
		gas         uint64
 | 
			
		||||
		expErr      bool
 | 
			
		||||
		errContains string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			"success",
 | 
			
		||||
			func(delAddr, valAddr string) []byte {
 | 
			
		||||
				input, err := s.abi.Pack(
 | 
			
		||||
					method,
 | 
			
		||||
					delAddr,
 | 
			
		||||
					valAddr,
 | 
			
		||||
				)
 | 
			
		||||
				s.Assert().NoError(err)
 | 
			
		||||
				return input
 | 
			
		||||
			},
 | 
			
		||||
			func(data []byte) {
 | 
			
		||||
				out, err := s.abi.Methods[method].Outputs.Unpack(data)
 | 
			
		||||
				s.Require().NoError(err, "failed to unpack output")
 | 
			
		||||
				v := out[0].(stakingprecompile.Validator)
 | 
			
		||||
				_ = v
 | 
			
		||||
				// jsonData, _ := json.MarshalIndent(v, "", "    ")
 | 
			
		||||
				// fmt.Printf("validators: %s\n", string(jsonData))
 | 
			
		||||
			},
 | 
			
		||||
			100000,
 | 
			
		||||
			false,
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		s.Run(tc.name, func() {
 | 
			
		||||
			s.SetupTest()
 | 
			
		||||
			operatorAddress, err := s.firstBondedValidator()
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
			d := s.stakingKeeper.GetValidatorDelegations(s.Ctx, operatorAddress)
 | 
			
		||||
			delAddr, err := sdk.AccAddressFromBech32(d[0].DelegatorAddress)
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
 | 
			
		||||
			bz, err := s.runTx(tc.malleate(delAddr.String(), operatorAddress.String()), s.signerOne, 10000000)
 | 
			
		||||
 | 
			
		||||
			if tc.expErr {
 | 
			
		||||
				s.Require().Error(err)
 | 
			
		||||
				s.Require().Contains(err.Error(), tc.errContains)
 | 
			
		||||
			} else {
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
				s.Require().NotNil(bz)
 | 
			
		||||
				tc.postCheck(bz)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *StakingTestSuite) TestPool() {
 | 
			
		||||
	method := stakingprecompile.StakingFunctionPool
 | 
			
		||||
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name        string
 | 
			
		||||
		malleate    func() []byte
 | 
			
		||||
		postCheck   func(bz []byte)
 | 
			
		||||
		gas         uint64
 | 
			
		||||
		expErr      bool
 | 
			
		||||
		errContains string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			"success",
 | 
			
		||||
			func() []byte {
 | 
			
		||||
				input, err := s.abi.Pack(
 | 
			
		||||
					method,
 | 
			
		||||
				)
 | 
			
		||||
				s.Assert().NoError(err)
 | 
			
		||||
				return input
 | 
			
		||||
			},
 | 
			
		||||
			func(data []byte) {
 | 
			
		||||
				out, err := s.abi.Methods[method].Outputs.Unpack(data)
 | 
			
		||||
				s.Require().NoError(err, "failed to unpack output")
 | 
			
		||||
				bonded := out[0].(*big.Int)
 | 
			
		||||
				unbonded := out[0].(*big.Int)
 | 
			
		||||
				s.Assert().Equal(bonded.Int64(), int64(0))
 | 
			
		||||
				s.Assert().Equal(unbonded.Int64(), int64(0))
 | 
			
		||||
			},
 | 
			
		||||
			100000,
 | 
			
		||||
			false,
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		s.Run(tc.name, func() {
 | 
			
		||||
			s.SetupTest()
 | 
			
		||||
 | 
			
		||||
			bz, err := s.runTx(tc.malleate(), s.signerOne, 10000000)
 | 
			
		||||
 | 
			
		||||
			if tc.expErr {
 | 
			
		||||
				s.Require().Error(err)
 | 
			
		||||
				s.Require().Contains(err.Error(), tc.errContains)
 | 
			
		||||
			} else {
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
				s.Require().NotNil(bz)
 | 
			
		||||
				tc.postCheck(bz)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *StakingTestSuite) TestParams() {
 | 
			
		||||
	method := stakingprecompile.StakingFunctionParams
 | 
			
		||||
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name        string
 | 
			
		||||
		malleate    func() []byte
 | 
			
		||||
		postCheck   func(bz []byte)
 | 
			
		||||
		gas         uint64
 | 
			
		||||
		expErr      bool
 | 
			
		||||
		errContains string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			"success",
 | 
			
		||||
			func() []byte {
 | 
			
		||||
				input, err := s.abi.Pack(
 | 
			
		||||
					method,
 | 
			
		||||
				)
 | 
			
		||||
				s.Assert().NoError(err)
 | 
			
		||||
				return input
 | 
			
		||||
			},
 | 
			
		||||
			func(data []byte) {
 | 
			
		||||
				out, err := s.abi.Methods[method].Outputs.Unpack(data)
 | 
			
		||||
				s.Require().NoError(err, "failed to unpack output")
 | 
			
		||||
				params := out[0].(stakingprecompile.Params)
 | 
			
		||||
				_ = params
 | 
			
		||||
				// jsonData, _ := json.MarshalIndent(params, "", "    ")
 | 
			
		||||
				// fmt.Printf("params: %s\n", string(jsonData))
 | 
			
		||||
			},
 | 
			
		||||
			100000,
 | 
			
		||||
			false,
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		s.Run(tc.name, func() {
 | 
			
		||||
			s.SetupTest()
 | 
			
		||||
 | 
			
		||||
			bz, err := s.runTx(tc.malleate(), s.signerOne, 10000000)
 | 
			
		||||
 | 
			
		||||
			if tc.expErr {
 | 
			
		||||
				s.Require().Error(err)
 | 
			
		||||
				s.Require().Contains(err.Error(), tc.errContains)
 | 
			
		||||
			} else {
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
				s.Require().NotNil(bz)
 | 
			
		||||
				tc.postCheck(bz)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										145
									
								
								precompiles/staking/staking_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								precompiles/staking/staking_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,145 @@
 | 
			
		||||
package staking_test
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"math/big"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"cosmossdk.io/math"
 | 
			
		||||
	stakingprecompile "github.com/0glabs/0g-chain/precompiles/staking"
 | 
			
		||||
	"github.com/0glabs/0g-chain/precompiles/testutil"
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
 | 
			
		||||
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
			
		||||
	stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
 | 
			
		||||
	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
 | 
			
		||||
	"github.com/ethereum/go-ethereum/accounts/abi"
 | 
			
		||||
	"github.com/ethereum/go-ethereum/common"
 | 
			
		||||
	"github.com/ethereum/go-ethereum/core/vm"
 | 
			
		||||
	evmtypes "github.com/evmos/ethermint/x/evm/types"
 | 
			
		||||
	"github.com/stretchr/testify/suite"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type StakingTestSuite struct {
 | 
			
		||||
	testutil.PrecompileTestSuite
 | 
			
		||||
 | 
			
		||||
	abi           abi.ABI
 | 
			
		||||
	addr          common.Address
 | 
			
		||||
	staking       *stakingprecompile.StakingPrecompile
 | 
			
		||||
	stakingKeeper *stakingkeeper.Keeper
 | 
			
		||||
	signerOne     *testutil.TestSigner
 | 
			
		||||
	signerTwo     *testutil.TestSigner
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (suite *StakingTestSuite) SetupTest() {
 | 
			
		||||
	suite.PrecompileTestSuite.SetupTest()
 | 
			
		||||
 | 
			
		||||
	suite.stakingKeeper = suite.App.GetStakingKeeper()
 | 
			
		||||
 | 
			
		||||
	suite.addr = common.HexToAddress(stakingprecompile.PrecompileAddress)
 | 
			
		||||
 | 
			
		||||
	precompiles := suite.EvmKeeper.GetPrecompiles()
 | 
			
		||||
	precompile, ok := precompiles[suite.addr]
 | 
			
		||||
	suite.Assert().EqualValues(ok, true)
 | 
			
		||||
 | 
			
		||||
	suite.staking = precompile.(*stakingprecompile.StakingPrecompile)
 | 
			
		||||
 | 
			
		||||
	suite.signerOne = suite.GenSigner()
 | 
			
		||||
	suite.signerTwo = suite.GenSigner()
 | 
			
		||||
 | 
			
		||||
	abi, err := abi.JSON(strings.NewReader(stakingprecompile.StakingABI))
 | 
			
		||||
	suite.Assert().NoError(err)
 | 
			
		||||
	suite.abi = abi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (suite *StakingTestSuite) AddDelegation(from string, to string, amount math.Int) {
 | 
			
		||||
	accAddr, err := sdk.AccAddressFromHexUnsafe(from)
 | 
			
		||||
	suite.Require().NoError(err)
 | 
			
		||||
	valAddr, err := sdk.ValAddressFromHex(to)
 | 
			
		||||
	suite.Require().NoError(err)
 | 
			
		||||
	validator, found := suite.StakingKeeper.GetValidator(suite.Ctx, valAddr)
 | 
			
		||||
	if !found {
 | 
			
		||||
		consPriv := ed25519.GenPrivKey()
 | 
			
		||||
		newValidator, err := stakingtypes.NewValidator(valAddr, consPriv.PubKey(), stakingtypes.Description{})
 | 
			
		||||
		suite.Require().NoError(err)
 | 
			
		||||
		validator = newValidator
 | 
			
		||||
	}
 | 
			
		||||
	validator.Tokens = validator.Tokens.Add(amount)
 | 
			
		||||
	validator.DelegatorShares = validator.DelegatorShares.Add(amount.ToLegacyDec())
 | 
			
		||||
	suite.StakingKeeper.SetValidator(suite.Ctx, validator)
 | 
			
		||||
	bonded := suite.stakingKeeper.GetDelegatorBonded(suite.Ctx, accAddr)
 | 
			
		||||
	suite.StakingKeeper.SetDelegation(suite.Ctx, stakingtypes.Delegation{
 | 
			
		||||
		DelegatorAddress: accAddr.String(),
 | 
			
		||||
		ValidatorAddress: valAddr.String(),
 | 
			
		||||
		Shares:           bonded.Add(amount).ToLegacyDec(),
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (suite *StakingTestSuite) setupValidator(signer *testutil.TestSigner) {
 | 
			
		||||
	method := stakingprecompile.StakingFunctionCreateValidator
 | 
			
		||||
	description := stakingprecompile.Description{
 | 
			
		||||
		Moniker:         "test node",
 | 
			
		||||
		Identity:        "test node identity",
 | 
			
		||||
		Website:         "http://test.node.com",
 | 
			
		||||
		SecurityContact: "test node security contract",
 | 
			
		||||
		Details:         "test node details",
 | 
			
		||||
	}
 | 
			
		||||
	commission := stakingprecompile.CommissionRates{
 | 
			
		||||
		Rate:          math.LegacyOneDec().BigInt(),
 | 
			
		||||
		MaxRate:       math.LegacyOneDec().BigInt(),
 | 
			
		||||
		MaxChangeRate: math.LegacyOneDec().BigInt(),
 | 
			
		||||
	}
 | 
			
		||||
	minSelfDelegation := big.NewInt(1)
 | 
			
		||||
	pubkey := "eh/aR8BGUBIYI/Ust0NVBxZafLDAm7344F9dKzZU+7g="
 | 
			
		||||
	value := big.NewInt(100000000)
 | 
			
		||||
	input, err := suite.abi.Pack(
 | 
			
		||||
		method,
 | 
			
		||||
		description,
 | 
			
		||||
		commission,
 | 
			
		||||
		minSelfDelegation,
 | 
			
		||||
		pubkey,
 | 
			
		||||
		value,
 | 
			
		||||
	)
 | 
			
		||||
	suite.Assert().NoError(err)
 | 
			
		||||
	_, err = suite.runTx(input, signer, 10000000)
 | 
			
		||||
	suite.Assert().NoError(err)
 | 
			
		||||
	_, err = suite.stakingKeeper.ApplyAndReturnValidatorSetUpdates(suite.Ctx)
 | 
			
		||||
	suite.Assert().NoError(err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (suite *StakingTestSuite) firstBondedValidator() (sdk.ValAddress, error) {
 | 
			
		||||
	validators := suite.stakingKeeper.GetValidators(suite.Ctx, 10)
 | 
			
		||||
	for _, v := range validators {
 | 
			
		||||
		if v.IsBonded() {
 | 
			
		||||
			return sdk.ValAddressFromBech32(v.OperatorAddress)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil, errors.New("no bonded validator")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (suite *StakingTestSuite) runTx(input []byte, signer *testutil.TestSigner, gas uint64) ([]byte, error) {
 | 
			
		||||
	contract := vm.NewPrecompile(vm.AccountRef(signer.Addr), vm.AccountRef(suite.addr), big.NewInt(0), gas)
 | 
			
		||||
	contract.Input = input
 | 
			
		||||
 | 
			
		||||
	msgEthereumTx := evmtypes.NewTx(suite.EvmKeeper.ChainID(), 0, &suite.addr, big.NewInt(0), gas, big.NewInt(0), big.NewInt(0), big.NewInt(0), input, nil)
 | 
			
		||||
	msgEthereumTx.From = signer.HexAddr
 | 
			
		||||
	err := msgEthereumTx.Sign(suite.EthSigner, signer.Signer)
 | 
			
		||||
	suite.Assert().NoError(err, "failed to sign Ethereum message")
 | 
			
		||||
 | 
			
		||||
	proposerAddress := suite.Ctx.BlockHeader().ProposerAddress
 | 
			
		||||
	cfg, err := suite.EvmKeeper.EVMConfig(suite.Ctx, proposerAddress, suite.EvmKeeper.ChainID())
 | 
			
		||||
	suite.Assert().NoError(err, "failed to instantiate EVM config")
 | 
			
		||||
 | 
			
		||||
	msg, err := msgEthereumTx.AsMessage(suite.EthSigner, big.NewInt(0))
 | 
			
		||||
	suite.Assert().NoError(err, "failed to instantiate Ethereum message")
 | 
			
		||||
 | 
			
		||||
	evm := suite.EvmKeeper.NewEVM(suite.Ctx, msg, cfg, nil, suite.Statedb)
 | 
			
		||||
	precompiles := suite.EvmKeeper.GetPrecompiles()
 | 
			
		||||
	evm.WithPrecompiles(precompiles, []common.Address{suite.addr})
 | 
			
		||||
 | 
			
		||||
	return suite.staking.Run(evm, contract, false)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestKeeperSuite(t *testing.T) {
 | 
			
		||||
	suite.Run(t, new(StakingTestSuite))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										163
									
								
								precompiles/staking/tx.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								precompiles/staking/tx.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,163 @@
 | 
			
		||||
package staking
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"math/big"
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
	response, err := stakingkeeper.NewMsgServerImpl(s.stakingKeeper).BeginRedelegate(ctx, msg)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	// emit events
 | 
			
		||||
	return method.Outputs.Pack(big.NewInt(response.CompletionTime.UTC().Unix()))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
	response, err := stakingkeeper.NewMsgServerImpl(s.stakingKeeper).Undelegate(ctx, msg)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	// emit events
 | 
			
		||||
	return method.Outputs.Pack(big.NewInt(response.CompletionTime.UTC().Unix()))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										485
									
								
								precompiles/staking/tx_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										485
									
								
								precompiles/staking/tx_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,485 @@
 | 
			
		||||
package staking_test
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/base64"
 | 
			
		||||
	"math/big"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"cosmossdk.io/math"
 | 
			
		||||
	stakingprecompile "github.com/0glabs/0g-chain/precompiles/staking"
 | 
			
		||||
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
			
		||||
	"github.com/ethereum/go-ethereum/common"
 | 
			
		||||
	"github.com/evmos/ethermint/x/evm/statedb"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (s *StakingTestSuite) TestCreateValidator() {
 | 
			
		||||
	method := stakingprecompile.StakingFunctionCreateValidator
 | 
			
		||||
	description := stakingprecompile.Description{
 | 
			
		||||
		Moniker:         "test node",
 | 
			
		||||
		Identity:        "test node identity",
 | 
			
		||||
		Website:         "http://test.node.com",
 | 
			
		||||
		SecurityContact: "test node security contract",
 | 
			
		||||
		Details:         "test node details",
 | 
			
		||||
	}
 | 
			
		||||
	commission := stakingprecompile.CommissionRates{
 | 
			
		||||
		Rate:          math.LegacyOneDec().BigInt(),
 | 
			
		||||
		MaxRate:       math.LegacyOneDec().BigInt(),
 | 
			
		||||
		MaxChangeRate: math.LegacyOneDec().BigInt(),
 | 
			
		||||
	}
 | 
			
		||||
	minSelfDelegation := big.NewInt(1)
 | 
			
		||||
	pubkey := "eh/aR8BGUBIYI/Ust0NVBxZafLDAm7344F9dKzZU+7g="
 | 
			
		||||
	value := big.NewInt(100000000)
 | 
			
		||||
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name          string
 | 
			
		||||
		malleate      func() []byte
 | 
			
		||||
		gas           uint64
 | 
			
		||||
		callerAddress *common.Address
 | 
			
		||||
		postCheck     func(data []byte)
 | 
			
		||||
		expError      bool
 | 
			
		||||
		errContains   string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			"fail - ErrPubKeyInvalidLength",
 | 
			
		||||
			func() []byte {
 | 
			
		||||
				input, err := s.abi.Pack(
 | 
			
		||||
					method,
 | 
			
		||||
					description,
 | 
			
		||||
					commission,
 | 
			
		||||
					minSelfDelegation,
 | 
			
		||||
					s.signerOne.HexAddr,
 | 
			
		||||
					value,
 | 
			
		||||
				)
 | 
			
		||||
				s.Assert().NoError(err)
 | 
			
		||||
				return input
 | 
			
		||||
			},
 | 
			
		||||
			200000,
 | 
			
		||||
			nil,
 | 
			
		||||
			func([]byte) {},
 | 
			
		||||
			true,
 | 
			
		||||
			stakingprecompile.ErrPubKeyInvalidLength,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"success",
 | 
			
		||||
			func() []byte {
 | 
			
		||||
				input, err := s.abi.Pack(
 | 
			
		||||
					method,
 | 
			
		||||
					description,
 | 
			
		||||
					commission,
 | 
			
		||||
					minSelfDelegation,
 | 
			
		||||
					pubkey,
 | 
			
		||||
					value,
 | 
			
		||||
				)
 | 
			
		||||
				s.Assert().NoError(err)
 | 
			
		||||
				return input
 | 
			
		||||
			},
 | 
			
		||||
			200000,
 | 
			
		||||
			nil,
 | 
			
		||||
			func(data []byte) {},
 | 
			
		||||
			false,
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		s.Run(tc.name, func() {
 | 
			
		||||
			s.SetupTest()
 | 
			
		||||
 | 
			
		||||
			bz, err := s.runTx(tc.malleate(), s.signerOne, 10000000)
 | 
			
		||||
			s.stakingKeeper.ApplyAndReturnValidatorSetUpdates(s.Ctx)
 | 
			
		||||
 | 
			
		||||
			if tc.expError {
 | 
			
		||||
				s.Require().ErrorContains(err, tc.errContains)
 | 
			
		||||
				s.Require().Empty(bz)
 | 
			
		||||
			} else {
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
				// query the validator in the staking keeper
 | 
			
		||||
				validator := s.StakingKeeper.Validator(s.Ctx, s.signerOne.ValAddr)
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
 | 
			
		||||
				s.Require().NotNil(validator, "expected validator not to be nil")
 | 
			
		||||
				tc.postCheck(bz)
 | 
			
		||||
 | 
			
		||||
				isBonded := validator.IsBonded()
 | 
			
		||||
				s.Require().Equal(true, isBonded, "expected validator bonded to be %t; got %t", true, isBonded)
 | 
			
		||||
 | 
			
		||||
				consPubKey, err := validator.ConsPubKey()
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
				consPubKeyBase64 := base64.StdEncoding.EncodeToString(consPubKey.Bytes())
 | 
			
		||||
				s.Require().Equal(pubkey, consPubKeyBase64, "expected validator pubkey to be %s; got %s", pubkey, consPubKeyBase64)
 | 
			
		||||
 | 
			
		||||
				operator := validator.GetOperator()
 | 
			
		||||
				s.Require().Equal(s.signerOne.ValAddr, operator, "expected validator operator to be %s; got %s", s.signerOne.ValAddr, operator)
 | 
			
		||||
 | 
			
		||||
				commissionRate := validator.GetCommission()
 | 
			
		||||
				s.Require().Equal(commission.Rate.String(), commissionRate.BigInt().String(), "expected validator commission rate to be %s; got %s", commission.Rate.String(), commissionRate.String())
 | 
			
		||||
 | 
			
		||||
				valMinSelfDelegation := validator.GetMinSelfDelegation()
 | 
			
		||||
				s.Require().Equal(minSelfDelegation.String(), valMinSelfDelegation.String(), "expected validator min self delegation to be %s; got %s", minSelfDelegation.String(), valMinSelfDelegation.String())
 | 
			
		||||
 | 
			
		||||
				moniker := validator.GetMoniker()
 | 
			
		||||
				s.Require().Equal(description.Moniker, moniker, "expected validator moniker to be %s; got %s", description.Moniker, moniker)
 | 
			
		||||
 | 
			
		||||
				jailed := validator.IsJailed()
 | 
			
		||||
				s.Require().Equal(false, jailed, "expected validator jailed to be %t; got %t", false, jailed)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *StakingTestSuite) TestEditValidator() {
 | 
			
		||||
	method := stakingprecompile.StakingFunctionEditValidator
 | 
			
		||||
	description := stakingprecompile.Description{
 | 
			
		||||
		Moniker:         "test node",
 | 
			
		||||
		Identity:        "test node identity",
 | 
			
		||||
		Website:         "http://test.node.com",
 | 
			
		||||
		SecurityContact: "test node security contract",
 | 
			
		||||
		Details:         "test node details",
 | 
			
		||||
	}
 | 
			
		||||
	newRate := math.LegacyOneDec().BigInt()
 | 
			
		||||
	newRate.Div(newRate, big.NewInt(2))
 | 
			
		||||
	minSelfDelegation := big.NewInt(2)
 | 
			
		||||
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name          string
 | 
			
		||||
		malleate      func() []byte
 | 
			
		||||
		gas           uint64
 | 
			
		||||
		callerAddress *common.Address
 | 
			
		||||
		postCheck     func(data []byte)
 | 
			
		||||
		expError      bool
 | 
			
		||||
		errContains   string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			"success",
 | 
			
		||||
			func() []byte {
 | 
			
		||||
				input, err := s.abi.Pack(
 | 
			
		||||
					method,
 | 
			
		||||
					description,
 | 
			
		||||
					stakingprecompile.NullableUint{
 | 
			
		||||
						IsNull: false,
 | 
			
		||||
						Value:  newRate,
 | 
			
		||||
					},
 | 
			
		||||
					stakingprecompile.NullableUint{
 | 
			
		||||
						IsNull: true,
 | 
			
		||||
						Value:  math.LegacyOneDec().BigInt(),
 | 
			
		||||
					},
 | 
			
		||||
				)
 | 
			
		||||
				s.Assert().NoError(err)
 | 
			
		||||
				return input
 | 
			
		||||
			},
 | 
			
		||||
			200000,
 | 
			
		||||
			nil,
 | 
			
		||||
			func(data []byte) {},
 | 
			
		||||
			false,
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		s.Run(tc.name, func() {
 | 
			
		||||
			s.SetupTest()
 | 
			
		||||
			s.setupValidator(s.signerOne)
 | 
			
		||||
			// move block time forward
 | 
			
		||||
			s.Ctx = s.Ctx.WithBlockTime(time.Now().Add(time.Hour * 100))
 | 
			
		||||
			s.Statedb = statedb.New(s.Ctx, s.EvmKeeper, statedb.NewEmptyTxConfig(common.BytesToHash(s.Ctx.HeaderHash().Bytes())))
 | 
			
		||||
 | 
			
		||||
			bz, err := s.runTx(tc.malleate(), s.signerOne, 10000000)
 | 
			
		||||
 | 
			
		||||
			if tc.expError {
 | 
			
		||||
				s.Require().ErrorContains(err, tc.errContains)
 | 
			
		||||
				s.Require().Empty(bz)
 | 
			
		||||
			} else {
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
				// query the validator in the staking keeper
 | 
			
		||||
				validator := s.StakingKeeper.Validator(s.Ctx, s.signerOne.ValAddr)
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
 | 
			
		||||
				s.Require().NotNil(validator, "expected validator not to be nil")
 | 
			
		||||
				tc.postCheck(bz)
 | 
			
		||||
 | 
			
		||||
				isBonded := validator.IsBonded()
 | 
			
		||||
				s.Require().Equal(true, isBonded, "expected validator bonded to be %t; got %t", false, isBonded)
 | 
			
		||||
 | 
			
		||||
				operator := validator.GetOperator()
 | 
			
		||||
				s.Require().Equal(s.signerOne.ValAddr, operator, "expected validator operator to be %s; got %s", s.signerOne.ValAddr, operator)
 | 
			
		||||
 | 
			
		||||
				commissionRate := validator.GetCommission()
 | 
			
		||||
				s.Require().Equal(newRate.String(), commissionRate.BigInt().String(), "expected validator commission rate to be %s; got %s", newRate.String(), commissionRate.String())
 | 
			
		||||
 | 
			
		||||
				valMinSelfDelegation := validator.GetMinSelfDelegation()
 | 
			
		||||
				s.Require().Equal(big.NewInt(1).String(), valMinSelfDelegation.String(), "expected validator min self delegation to be %s; got %s", minSelfDelegation.String(), valMinSelfDelegation.String())
 | 
			
		||||
 | 
			
		||||
				moniker := validator.GetMoniker()
 | 
			
		||||
				s.Require().Equal(description.Moniker, moniker, "expected validator moniker to be %s; got %s", description.Moniker, moniker)
 | 
			
		||||
 | 
			
		||||
				jailed := validator.IsJailed()
 | 
			
		||||
				s.Require().Equal(false, jailed, "expected validator jailed to be %t; got %t", false, jailed)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *StakingTestSuite) TestDelegate() {
 | 
			
		||||
	method := stakingprecompile.StakingFunctionDelegate
 | 
			
		||||
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name          string
 | 
			
		||||
		malleate      func(valAddr string) []byte
 | 
			
		||||
		gas           uint64
 | 
			
		||||
		callerAddress *common.Address
 | 
			
		||||
		postCheck     func(valAddr sdk.ValAddress)
 | 
			
		||||
		expError      bool
 | 
			
		||||
		errContains   string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			"success",
 | 
			
		||||
			func(valAddr string) []byte {
 | 
			
		||||
				input, err := s.abi.Pack(
 | 
			
		||||
					method,
 | 
			
		||||
					valAddr,
 | 
			
		||||
					big.NewInt(1000000),
 | 
			
		||||
				)
 | 
			
		||||
				s.Assert().NoError(err)
 | 
			
		||||
				return input
 | 
			
		||||
			},
 | 
			
		||||
			200000,
 | 
			
		||||
			nil,
 | 
			
		||||
			func(valAddr sdk.ValAddress) {
 | 
			
		||||
				d, found := s.stakingKeeper.GetDelegation(s.Ctx, s.signerOne.AccAddr, valAddr)
 | 
			
		||||
				s.Assert().EqualValues(found, true)
 | 
			
		||||
				s.Assert().EqualValues(d.ValidatorAddress, valAddr.String())
 | 
			
		||||
				s.Assert().EqualValues(d.DelegatorAddress, s.signerOne.AccAddr.String())
 | 
			
		||||
 | 
			
		||||
				// jsonData, _ := json.MarshalIndent(d, "", "    ")
 | 
			
		||||
				// fmt.Printf("delegation: %s\n", string(jsonData))
 | 
			
		||||
			},
 | 
			
		||||
			false,
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		s.Run(tc.name, func() {
 | 
			
		||||
			s.SetupTest()
 | 
			
		||||
 | 
			
		||||
			operatorAddress, err := s.firstBondedValidator()
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
 | 
			
		||||
			bz, err := s.runTx(tc.malleate(operatorAddress.String()), s.signerOne, 10000000)
 | 
			
		||||
 | 
			
		||||
			if tc.expError {
 | 
			
		||||
				s.Require().ErrorContains(err, tc.errContains)
 | 
			
		||||
				s.Require().Empty(bz)
 | 
			
		||||
			} else {
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
				tc.postCheck(operatorAddress)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *StakingTestSuite) TestBeginRedelegate() {
 | 
			
		||||
	method := stakingprecompile.StakingFunctionBeginRedelegate
 | 
			
		||||
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name          string
 | 
			
		||||
		malleate      func(srcAddr, dstAddr string) []byte
 | 
			
		||||
		gas           uint64
 | 
			
		||||
		callerAddress *common.Address
 | 
			
		||||
		postCheck     func(data []byte, srcAddr, dstAddr sdk.ValAddress)
 | 
			
		||||
		expError      bool
 | 
			
		||||
		errContains   string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			"success",
 | 
			
		||||
			func(srcAddr, dstAddr string) []byte {
 | 
			
		||||
				input, err := s.abi.Pack(
 | 
			
		||||
					method,
 | 
			
		||||
					srcAddr,
 | 
			
		||||
					dstAddr,
 | 
			
		||||
					big.NewInt(1000000),
 | 
			
		||||
				)
 | 
			
		||||
				s.Assert().NoError(err)
 | 
			
		||||
				return input
 | 
			
		||||
			},
 | 
			
		||||
			200000,
 | 
			
		||||
			nil,
 | 
			
		||||
			func(data []byte, srcAddr, dstAddr sdk.ValAddress) {
 | 
			
		||||
				out, err := s.abi.Methods[method].Outputs.Unpack(data)
 | 
			
		||||
				s.Require().NoError(err, "failed to unpack output")
 | 
			
		||||
 | 
			
		||||
				d, found := s.stakingKeeper.GetRedelegation(s.Ctx, s.signerOne.AccAddr, srcAddr, dstAddr)
 | 
			
		||||
				s.Assert().EqualValues(found, true)
 | 
			
		||||
				s.Assert().EqualValues(d.DelegatorAddress, s.signerOne.AccAddr.String())
 | 
			
		||||
				s.Assert().EqualValues(d.ValidatorSrcAddress, srcAddr.String())
 | 
			
		||||
				s.Assert().EqualValues(d.ValidatorDstAddress, dstAddr.String())
 | 
			
		||||
 | 
			
		||||
				completionTime := out[0].(*big.Int)
 | 
			
		||||
				params := s.stakingKeeper.GetParams(s.Ctx)
 | 
			
		||||
				s.Assert().EqualValues(completionTime.Int64(), s.Ctx.BlockHeader().Time.Add(params.UnbondingTime).UTC().Unix())
 | 
			
		||||
				// jsonData, _ := json.MarshalIndent(d, "", "    ")
 | 
			
		||||
				// fmt.Printf("redelegation: %s\n", string(jsonData))
 | 
			
		||||
			},
 | 
			
		||||
			false,
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		s.Run(tc.name, func() {
 | 
			
		||||
			s.SetupTest()
 | 
			
		||||
			operatorAddress, err := s.firstBondedValidator()
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
 | 
			
		||||
			// move block time forward
 | 
			
		||||
			s.Ctx = s.Ctx.WithBlockTime(time.Now().Add(time.Hour * 100))
 | 
			
		||||
			s.Statedb = statedb.New(s.Ctx, s.EvmKeeper, statedb.NewEmptyTxConfig(common.BytesToHash(s.Ctx.HeaderHash().Bytes())))
 | 
			
		||||
 | 
			
		||||
			s.setupValidator(s.signerOne)
 | 
			
		||||
 | 
			
		||||
			bz, err := s.runTx(tc.malleate(s.signerOne.ValAddr.String(), operatorAddress.String()), s.signerOne, 10000000)
 | 
			
		||||
 | 
			
		||||
			if tc.expError {
 | 
			
		||||
				s.Require().ErrorContains(err, tc.errContains)
 | 
			
		||||
				s.Require().Empty(bz)
 | 
			
		||||
			} else {
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
				tc.postCheck(bz, s.signerOne.ValAddr, operatorAddress)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *StakingTestSuite) TestUndelegate() {
 | 
			
		||||
	method := stakingprecompile.StakingFunctionUndelegate
 | 
			
		||||
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name          string
 | 
			
		||||
		malleate      func(valAddr string) []byte
 | 
			
		||||
		gas           uint64
 | 
			
		||||
		callerAddress *common.Address
 | 
			
		||||
		postCheck     func(data []byte, valAddr sdk.ValAddress)
 | 
			
		||||
		expError      bool
 | 
			
		||||
		errContains   string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			"success",
 | 
			
		||||
			func(valAddr string) []byte {
 | 
			
		||||
				input, err := s.abi.Pack(
 | 
			
		||||
					method,
 | 
			
		||||
					valAddr,
 | 
			
		||||
					big.NewInt(1000000),
 | 
			
		||||
				)
 | 
			
		||||
				s.Assert().NoError(err)
 | 
			
		||||
				return input
 | 
			
		||||
			},
 | 
			
		||||
			200000,
 | 
			
		||||
			nil,
 | 
			
		||||
			func(data []byte, valAddr sdk.ValAddress) {
 | 
			
		||||
				out, err := s.abi.Methods[method].Outputs.Unpack(data)
 | 
			
		||||
				s.Require().NoError(err, "failed to unpack output")
 | 
			
		||||
 | 
			
		||||
				d, found := s.stakingKeeper.GetUnbondingDelegation(s.Ctx, s.signerOne.AccAddr, valAddr)
 | 
			
		||||
				s.Assert().EqualValues(found, true)
 | 
			
		||||
				s.Assert().EqualValues(d.DelegatorAddress, s.signerOne.AccAddr.String())
 | 
			
		||||
				s.Assert().EqualValues(d.ValidatorAddress, valAddr.String())
 | 
			
		||||
 | 
			
		||||
				completionTime := out[0].(*big.Int)
 | 
			
		||||
				params := s.stakingKeeper.GetParams(s.Ctx)
 | 
			
		||||
				s.Assert().EqualValues(completionTime.Int64(), s.Ctx.BlockHeader().Time.Add(params.UnbondingTime).UTC().Unix())
 | 
			
		||||
				// jsonData, _ := json.MarshalIndent(d, "", "    ")
 | 
			
		||||
				// fmt.Printf("redelegation: %s\n", string(jsonData))
 | 
			
		||||
			},
 | 
			
		||||
			false,
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		s.Run(tc.name, func() {
 | 
			
		||||
			s.SetupTest()
 | 
			
		||||
 | 
			
		||||
			// move block time forward
 | 
			
		||||
			s.Ctx = s.Ctx.WithBlockTime(time.Now().Add(time.Hour * 100))
 | 
			
		||||
			s.Statedb = statedb.New(s.Ctx, s.EvmKeeper, statedb.NewEmptyTxConfig(common.BytesToHash(s.Ctx.HeaderHash().Bytes())))
 | 
			
		||||
 | 
			
		||||
			s.setupValidator(s.signerOne)
 | 
			
		||||
 | 
			
		||||
			bz, err := s.runTx(tc.malleate(s.signerOne.ValAddr.String()), s.signerOne, 10000000)
 | 
			
		||||
 | 
			
		||||
			if tc.expError {
 | 
			
		||||
				s.Require().ErrorContains(err, tc.errContains)
 | 
			
		||||
				s.Require().Empty(bz)
 | 
			
		||||
			} else {
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
				tc.postCheck(bz, s.signerOne.ValAddr)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *StakingTestSuite) TestCancelUnbondingDelegation() {
 | 
			
		||||
	method := stakingprecompile.StakingFunctionCancelUnbondingDelegation
 | 
			
		||||
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name          string
 | 
			
		||||
		malleate      func(valAddr string, height *big.Int) []byte
 | 
			
		||||
		gas           uint64
 | 
			
		||||
		callerAddress *common.Address
 | 
			
		||||
		postCheck     func(valAddr sdk.ValAddress)
 | 
			
		||||
		expError      bool
 | 
			
		||||
		errContains   string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			"success",
 | 
			
		||||
			func(valAddr string, height *big.Int) []byte {
 | 
			
		||||
				input, err := s.abi.Pack(
 | 
			
		||||
					method,
 | 
			
		||||
					valAddr,
 | 
			
		||||
					big.NewInt(1),
 | 
			
		||||
					height,
 | 
			
		||||
				)
 | 
			
		||||
				s.Assert().NoError(err)
 | 
			
		||||
				return input
 | 
			
		||||
			},
 | 
			
		||||
			200000,
 | 
			
		||||
			nil,
 | 
			
		||||
			func(valAddr sdk.ValAddress) {
 | 
			
		||||
				_, found := s.stakingKeeper.GetUnbondingDelegation(s.Ctx, s.signerOne.AccAddr, valAddr)
 | 
			
		||||
				s.Assert().EqualValues(found, false)
 | 
			
		||||
				// jsonData, _ := json.MarshalIndent(d, "", "    ")
 | 
			
		||||
				// fmt.Printf("redelegation: %s\n", string(jsonData))
 | 
			
		||||
			},
 | 
			
		||||
			false,
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		s.Run(tc.name, func() {
 | 
			
		||||
			s.SetupTest()
 | 
			
		||||
 | 
			
		||||
			// move block time forward
 | 
			
		||||
			s.Ctx = s.Ctx.WithBlockTime(time.Now().Add(time.Hour * 100))
 | 
			
		||||
			s.Statedb = statedb.New(s.Ctx, s.EvmKeeper, statedb.NewEmptyTxConfig(common.BytesToHash(s.Ctx.HeaderHash().Bytes())))
 | 
			
		||||
 | 
			
		||||
			s.setupValidator(s.signerOne)
 | 
			
		||||
			// unbond
 | 
			
		||||
			_, err := s.stakingKeeper.Undelegate(s.Ctx, s.signerOne.AccAddr, s.signerOne.ValAddr, sdk.NewDec(1))
 | 
			
		||||
			s.Require().NoError(err)
 | 
			
		||||
 | 
			
		||||
			u, _ := s.stakingKeeper.GetUnbondingDelegation(s.Ctx, s.signerOne.AccAddr, s.signerOne.ValAddr)
 | 
			
		||||
			height := u.Entries[0].CreationHeight
 | 
			
		||||
 | 
			
		||||
			bz, err := s.runTx(tc.malleate(s.signerOne.ValAddr.String(), big.NewInt(height)), s.signerOne, 10000000)
 | 
			
		||||
 | 
			
		||||
			if tc.expError {
 | 
			
		||||
				s.Require().ErrorContains(err, tc.errContains)
 | 
			
		||||
				s.Require().Empty(bz)
 | 
			
		||||
			} else {
 | 
			
		||||
				s.Require().NoError(err)
 | 
			
		||||
				tc.postCheck(s.signerOne.ValAddr)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										602
									
								
								precompiles/staking/types.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										602
									
								
								precompiles/staking/types.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,602 @@
 | 
			
		||||
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 {
 | 
			
		||||
	if pagination == nil {
 | 
			
		||||
		return PageResponse{
 | 
			
		||||
			NextKey: make([]byte, 0),
 | 
			
		||||
			Total:   1,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	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)
 | 
			
		||||
	msg := &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)},
 | 
			
		||||
	}
 | 
			
		||||
	return msg, msg.ValidateBasic()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	msg := &stakingtypes.MsgEditValidator{
 | 
			
		||||
		Description:       convertStakingDescription(description),
 | 
			
		||||
		CommissionRate:    commissionRate,
 | 
			
		||||
		ValidatorAddress:  sdk.ValAddress(sender.Bytes()).String(),
 | 
			
		||||
		MinSelfDelegation: minSelfDelegation,
 | 
			
		||||
	}
 | 
			
		||||
	return msg, msg.ValidateBasic()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
 | 
			
		||||
	msg := &stakingtypes.MsgDelegate{
 | 
			
		||||
		DelegatorAddress: sdk.AccAddress(sender.Bytes()).String(),
 | 
			
		||||
		ValidatorAddress: validatorAddress,
 | 
			
		||||
		Amount:           sdk.Coin{Denom: denom, Amount: math.NewIntFromBigInt(amount)},
 | 
			
		||||
	}
 | 
			
		||||
	return msg, msg.ValidateBasic()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
 | 
			
		||||
	msg := &stakingtypes.MsgBeginRedelegate{
 | 
			
		||||
		DelegatorAddress:    sdk.AccAddress(sender.Bytes()).String(),
 | 
			
		||||
		ValidatorSrcAddress: validatorSrcAddress,
 | 
			
		||||
		ValidatorDstAddress: validatorDstAddress,
 | 
			
		||||
		Amount:              sdk.Coin{Denom: denom, Amount: math.NewIntFromBigInt(amount)},
 | 
			
		||||
	}
 | 
			
		||||
	return msg, msg.ValidateBasic()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
 | 
			
		||||
	msg := &stakingtypes.MsgUndelegate{
 | 
			
		||||
		DelegatorAddress: sdk.AccAddress(sender.Bytes()).String(),
 | 
			
		||||
		ValidatorAddress: validatorAddress,
 | 
			
		||||
		Amount:           sdk.Coin{Denom: denom, Amount: math.NewIntFromBigInt(amount)},
 | 
			
		||||
	}
 | 
			
		||||
	return msg, msg.ValidateBasic()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
 | 
			
		||||
	msg := &stakingtypes.MsgCancelUnbondingDelegation{
 | 
			
		||||
		DelegatorAddress: sdk.AccAddress(sender.Bytes()).String(),
 | 
			
		||||
		ValidatorAddress: validatorAddress,
 | 
			
		||||
		Amount:           sdk.Coin{Denom: denom, Amount: math.NewIntFromBigInt(amount)},
 | 
			
		||||
		CreationHeight:   creationHeight.Int64(),
 | 
			
		||||
	}
 | 
			
		||||
	return msg, msg.ValidateBasic()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
}
 | 
			
		||||
@ -1,11 +1,13 @@
 | 
			
		||||
package testutil
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"math/big"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"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"
 | 
			
		||||
@ -44,15 +46,25 @@ type TestSigner struct {
 | 
			
		||||
	HexAddr string
 | 
			
		||||
	PrivKey cryptotypes.PrivKey
 | 
			
		||||
	Signer  keyring.Signer
 | 
			
		||||
	ValAddr sdk.ValAddress
 | 
			
		||||
	AccAddr sdk.AccAddress
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GenSigner() *TestSigner {
 | 
			
		||||
func (suite *PrecompileTestSuite) GenSigner() *TestSigner {
 | 
			
		||||
	var s 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)
 | 
			
		||||
	valAddr, _ := sdk.ValAddressFromHex(s.HexAddr)
 | 
			
		||||
	accAddr, _ := sdk.AccAddressFromHexUnsafe(s.HexAddr)
 | 
			
		||||
	s.ValAddr = valAddr
 | 
			
		||||
	s.AccAddr = accAddr
 | 
			
		||||
 | 
			
		||||
	// 10000 a0gi for test
 | 
			
		||||
	suite.App.GetBankKeeper().MintCoins(suite.Ctx, "mint", sdk.NewCoins(chaincfg.MakeCoinForGasDenom(big.NewInt(10000000000))))
 | 
			
		||||
	suite.App.GetBankKeeper().SendCoinsFromModuleToAccount(suite.Ctx, "mint", accAddr, sdk.NewCoins(chaincfg.MakeCoinForGasDenom(big.NewInt(10000000000))))
 | 
			
		||||
	return &s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -70,7 +82,7 @@ func (suite *PrecompileTestSuite) SetupTest() {
 | 
			
		||||
	hexAddr := strings.ToLower(crypto.PubkeyToAddress(key.PublicKey).Hex()[2:])
 | 
			
		||||
	valAddr, err := sdk.ValAddressFromHex(hexAddr)
 | 
			
		||||
	suite.Assert().NoError(err)
 | 
			
		||||
	suite.Ctx = suite.App.NewContext(true, tmproto.Header{Height: 1, ChainID: app.TestChainId, ProposerAddress: consAddress})
 | 
			
		||||
	suite.Ctx = suite.App.NewContext(true, tmproto.Header{Height: 1, ChainID: app.TestChainId, ProposerAddress: consAddress, Time: time.Now()})
 | 
			
		||||
	newValidator, err := stakingtypes.NewValidator(valAddr, privkey.PubKey(), stakingtypes.Description{})
 | 
			
		||||
	suite.Assert().NoError(err)
 | 
			
		||||
	err = suite.StakingKeeper.SetValidatorByConsAddr(suite.Ctx, newValidator)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user