Skip to content

Commit

Permalink
refine some RPCs regarding asset and delegation
Browse files Browse the repository at this point in the history
  • Loading branch information
TimmyExogenous committed Feb 23, 2025
1 parent 8ed5a43 commit 22ae0d5
Show file tree
Hide file tree
Showing 19 changed files with 2,206 additions and 483 deletions.
6 changes: 2 additions & 4 deletions client/docs/statik/statik.go

Large diffs are not rendered by default.

355 changes: 323 additions & 32 deletions client/docs/swagger-ui/swagger.json

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions precompiles/assets/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,11 @@ func (p Precompile) GetStakerBalanceByToken(
ClientChainID: clientChainID,
StakerAddress: stakerAddress,
TokenID: assetAddress,
Balance: balance.Balance,
Withdrawable: balance.Withdrawable,
Delegated: balance.Delegated,
PendingUndelegated: balance.PendingUndelegated,
TotalDeposited: balance.TotalDeposited,
Balance: balance.Balance.BigInt(),
Withdrawable: balance.Withdrawable.BigInt(),
Delegated: balance.Delegated.BigInt(),
PendingUndelegated: balance.PendingUndelegated.BigInt(),
TotalDeposited: balance.TotalDeposited.BigInt(),
}

return method.Outputs.Pack(true, result)
Expand Down
3 changes: 1 addition & 2 deletions precompiles/avs/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ var baseTestCases = []avsTestCases{

func (suite *AVSManagerPrecompileSuite) TestGetOptedInOperatorAccAddrs() {
method := suite.precompile.Methods[avsManagerPrecompile.MethodGetOptInOperators]
operatorAddress, avsAddress, slashContract :=
sdk.AccAddress(utiltx.GenerateAddress().Bytes()).String(), suite.Address, "0xDF907c29719154eb9872f021d21CAE6E5025d7aB"
operatorAddress, avsAddress, slashContract := sdk.AccAddress(utiltx.GenerateAddress().Bytes()).String(), suite.Address, "0xDF907c29719154eb9872f021d21CAE6E5025d7aB"

operatorOptIn := func() {
optedInfo := &types.OptedInfo{
Expand Down
61 changes: 61 additions & 0 deletions proto/imuachain/assets/v1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,62 @@ message QueryParamsResponse {
Params params = 1;
}

// StakerBalance is a struct to describe the balance of a staker for a specific asset
// balance = withdrawable + delegated + pendingUndelegated
// pendingUndelegated is the amount of the asset that is during unbonding period and not yet withdrawable
// it would finally be withdrawable after the unbonding period, but the final amount may be less than the pendingUndelegated
// because of the penalty during the unbonding period
message StakerBalance {
// staker_id is the staker id for which the query is made.
string staker_id = 1;
// asset_id is the asset for which the query is made.
string asset_id = 2;
// balance = withdrawable + delegated + pendingUndelegated
string balance = 3 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
// withdrawable is the amount that can be withdrawn
string withdrawable = 4 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
// delegated is the amount that has been delegated to the operators
string delegated = 5 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
// pending_undelegated is the amount that has been undelegated but not been completed
string pending_undelegated = 6 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
// total_deposited is the total deposit amount, compared to the balance, it might include slashed amount
string total_deposited = 7 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
}

// QueryStakerBalanceRequest is the request type for the Query/QueryStakerBalance RPC method.
message QueryStakerBalanceRequest {
// staker_id is the staker id for which the query is made.
string staker_id = 1;
// asset_id is the asset for which the query is made.
string asset_id = 2;
}

// QueryStakerBalanceResponse is the response type for the Query/QueryStakerBalance RPC method.
message QueryStakerBalanceResponse {
// staker_balance is the response for QueryStakerBalanceRequest
StakerBalance staker_balance = 1;
}

// Query defines the gRPC query service for the assets module.
service Query {
// Params retrieves the assets module params
Expand Down Expand Up @@ -146,4 +202,9 @@ service Query {
option (cosmos.query.v1.module_query_safe) = true;
option (google.api.http).get = "/imuachain/assets/v1/operator_asset/{operator_addr}/{asset_id}";
}
// QueryStakerBalance queries the staker balance for specified asset
rpc QueryStakerBalance(QueryStakerBalanceRequest) returns (QueryStakerBalanceResponse) {
option (cosmos.query.v1.module_query_safe) = true;
option (google.api.http).get = "/imuachain/assets/v1/staker_balance/{staker_id}/{asset_id}";
}
}
33 changes: 23 additions & 10 deletions proto/imuachain/delegation/v1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,31 @@ message DelegationAmounts {
];
}

// SingleDelegationInfo includes the share, amount and pending undelegation amount
message SingleDelegationInfo {
// delegation_amounts is the delegation info recorded in the KVStore
DelegationAmounts delegation_amounts = 1 ;
// max_undelegatable_amount is the maximum amount that can be undelegated
string max_undelegatable_amount = 2 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
}

// DelegationInfoAndOperator includes the SingleDelegationInfo and operator address
message DelegationInfoAndOperator {
// operator is the operator address of this delegation
string operator = 1;
// delegation_info is the delegation information
SingleDelegationInfo delegation_info = 2;
}

// QueryDelegationInfoResponse is the response for delegations by staker id and
// asset id.
message QueryDelegationInfoResponse {

Check failure on line 76 in proto/imuachain/delegation/v1/query.proto

View workflow job for this annotation

GitHub Actions / proto-break-check

Previously present message "QueryDelegationInfoResponse.DelegationInfosEntry" was deleted from file.
// delegation_infos is the delegation information for each operator.
map<string, DelegationAmounts> delegation_infos = 1;
repeated DelegationInfoAndOperator delegation_infos = 1;

Check failure on line 78 in proto/imuachain/delegation/v1/query.proto

View workflow job for this annotation

GitHub Actions / proto-break-check

Field "1" on message "QueryDelegationInfoResponse" changed type from "imuachain.delegation.v1.QueryDelegationInfoResponse.DelegationInfosEntry" to "imuachain.delegation.v1.DelegationInfoAndOperator".
}

// SingleDelegationInfoReq is the request to obtain the single delegation information
Expand All @@ -71,14 +91,8 @@ message SingleDelegationInfoReq {

// SingleDelegationInfoResponse is the response to QuerySingleDelegationInfo
message SingleDelegationInfoResponse {

Check failure on line 93 in proto/imuachain/delegation/v1/query.proto

View workflow job for this annotation

GitHub Actions / proto-break-check

Previously present field "2" with name "max_undelegatable_amount" on message "SingleDelegationInfoResponse" was deleted.
// delegation_amounts is the delegation info recorded in the KVStore
DelegationAmounts delegation_amounts = 1;
// max_undelegatable_amount is the maximum amount that can be undelegated
string max_undelegatable_amount = 2 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
// single_delegation_info
SingleDelegationInfo single_delegation_info = 1 ;

Check failure on line 95 in proto/imuachain/delegation/v1/query.proto

View workflow job for this annotation

GitHub Actions / proto-break-check

Field "1" with name "single_delegation_info" on message "SingleDelegationInfoResponse" changed option "json_name" from "delegationAmounts" to "singleDelegationInfo".

Check failure on line 95 in proto/imuachain/delegation/v1/query.proto

View workflow job for this annotation

GitHub Actions / proto-break-check

Field "1" on message "SingleDelegationInfoResponse" changed type from "imuachain.delegation.v1.DelegationAmounts" to "imuachain.delegation.v1.SingleDelegationInfo".

Check failure on line 95 in proto/imuachain/delegation/v1/query.proto

View workflow job for this annotation

GitHub Actions / proto-break-check

Field "1" on message "SingleDelegationInfoResponse" changed name from "delegation_amounts" to "single_delegation_info".
}

// UndelegationHoldCountReq is the request to obtain the undelegation hold count.
Expand Down Expand Up @@ -221,5 +235,4 @@ service Query {
option (cosmos.query.v1.module_query_safe) = true;
option (google.api.http).get = "/imuachain/delegation/v1/delegated_stakers/{operator}/{asset_id}";
}

}
2 changes: 1 addition & 1 deletion testutil/batch/tx_check.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (m *Manager) QueryDelegatedAmount(clientChainLzID uint64, stakerAddr, asset
if err != nil {
return sdkmath.ZeroInt(), err
}
return delegationInfo.MaxUndelegatableAmount, nil
return delegationInfo.SingleDelegationInfo.MaxUndelegatableAmount, nil
}

func (m *Manager) PrecompileTxOnChainCheck(batchID uint, msgType string) error {
Expand Down
11 changes: 11 additions & 0 deletions x/assets/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,14 @@ func (k Keeper) QueOperatorSpecifiedAssetAmount(ctx context.Context, req *assets
}
return k.GetOperatorSpecifiedAssetInfo(c, addr, strings.ToLower(req.AssetId))
}

func (k Keeper) QueryStakerBalance(ctx context.Context, req *assetstype.QueryStakerBalanceRequest) (*assetstype.QueryStakerBalanceResponse, error) {
c := sdk.UnwrapSDKContext(ctx)
stakerBalance, err := k.GetStakerBalanceByAsset(c, strings.ToLower(req.StakerId), strings.ToLower(req.AssetId))
if err != nil {
return nil, err
}
return &assetstype.QueryStakerBalanceResponse{
StakerBalance: &stakerBalance,
}, nil
}
36 changes: 13 additions & 23 deletions x/assets/keeper/staker_asset.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@ package keeper
import (
"fmt"

"github.com/ethereum/go-ethereum/common/hexutil"
assetstype "github.com/imua-xyz/imuachain/x/assets/types"
delegationkeeper "github.com/imua-xyz/imuachain/x/delegation/keeper"

errorsmod "cosmossdk.io/errors"
"cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/common/hexutil"
assetstype "github.com/imua-xyz/imuachain/x/assets/types"
)

// AllDeposits
Expand Down Expand Up @@ -99,21 +97,13 @@ func (k Keeper) GetStakerSpecifiedAssetInfo(ctx sdk.Context, stakerID string, as
if err != nil {
return nil, errorsmod.Wrap(err, "failed to GetDelegationInfo")
}
for operator, record := range delegationInfoRecords.DelegationInfos {
operatorAssetInfo, err := k.GetOperatorSpecifiedAssetInfo(ctx, sdk.MustAccAddressFromBech32(operator), assetID)
if err != nil {
return nil, errorsmod.Wrap(err, "failed to GetOperatorSpecifiedAssetInfo")
}
// the `undelegatableTokens` are currently delegated tokens. they are post-slashing, if any is applied.
for _, delegationInfo := range delegationInfoRecords.DelegationInfos {
// the `MaxUndelegatableAmount` are currently delegated tokens. they are post-slashing, if any is applied.
// this is because slashing is applied to an operator's total amount, of which, the share of a staker is kept
// unchanged.
undelegatableTokens, err := delegationkeeper.TokensFromShares(record.UndelegatableShare, operatorAssetInfo.TotalShare, operatorAssetInfo.TotalAmount)
if err != nil {
return nil, errorsmod.Wrap(err, "failed to get shares from token")
}
// this amount is post-slashing, as explained above.
info.TotalDepositAmount = info.TotalDepositAmount.Add(undelegatableTokens).Add(record.WaitUndelegationAmount)
info.PendingUndelegationAmount = info.PendingUndelegationAmount.Add(record.WaitUndelegationAmount)
info.TotalDepositAmount = info.TotalDepositAmount.Add(delegationInfo.DelegationInfo.MaxUndelegatableAmount).Add(delegationInfo.DelegationInfo.DelegationAmounts.WaitUndelegationAmount)
info.PendingUndelegationAmount = info.PendingUndelegationAmount.Add(delegationInfo.DelegationInfo.DelegationAmounts.WaitUndelegationAmount)
}
return info, nil
}
Expand Down Expand Up @@ -216,13 +206,13 @@ func (k Keeper) GetStakerBalanceByAsset(ctx sdk.Context, stakerID string, assetI
totalBalance := stakerAssetInfo.WithdrawableAmount.Add(stakerAssetInfo.PendingUndelegationAmount).Add(delegatedAmount)

balance = assetstype.StakerBalance{
StakerID: stakerID,
AssetID: assetID,
Balance: totalBalance.BigInt(),
Withdrawable: stakerAssetInfo.WithdrawableAmount.BigInt(),
Delegated: delegatedAmount.BigInt(),
PendingUndelegated: stakerAssetInfo.PendingUndelegationAmount.BigInt(),
TotalDeposited: stakerAssetInfo.TotalDepositAmount.BigInt(),
StakerId: stakerID,
AssetId: assetID,
Balance: totalBalance,
Withdrawable: stakerAssetInfo.WithdrawableAmount,
Delegated: delegatedAmount,
PendingUndelegated: stakerAssetInfo.PendingUndelegationAmount,
TotalDeposited: stakerAssetInfo.TotalDepositAmount,
}

return balance, nil
Expand Down
5 changes: 2 additions & 3 deletions x/assets/types/general.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package types

import (
"fmt"
"math/big"
"strings"

"github.com/imua-xyz/imuachain/utils"
Expand Down Expand Up @@ -98,15 +97,15 @@ type CreateQueryContext func(height int64, prove bool) (sdk.Context, error)
// pendingUndelegated is the amount of the asset that is during unbonding period and not yet withdrawable
// it would finally be withdrawable after the unbonding period, but the final amount may be less than the pendingUndelegated
// because of the penalty during the unbonding period
type StakerBalance struct {
/*type StakerBalance struct {
StakerID string
AssetID string
Balance *big.Int
Withdrawable *big.Int
Delegated *big.Int
PendingUndelegated *big.Int
TotalDeposited *big.Int
}
}*/

// GetStakerIDAndAssetID stakerID = stakerAddress+'_'+clientChainLzID,assetID =
// assetAddress+'_'+clientChainLzID
Expand Down
Loading

0 comments on commit 22ae0d5

Please sign in to comment.