Skip to content

Commit

Permalink
fix: Send LSM redeem messages in chunks (#727)
Browse files Browse the repository at this point in the history
* send LSM redeem messages in chunks

* changelog

* linting
  • Loading branch information
kruspy authored Jan 19, 2024
1 parent ce9c73f commit 7d81888
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 48 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Bug Fixes

- [727](https://github.com/persistenceOne/pstake-native/pull/727) Send LSM redeem messages in chunks.
- [726](https://github.com/persistenceOne/pstake-native/pull/726) Fix minimal unbondings.
- [720](https://github.com/persistenceOne/pstake-native/pull/720) Fix unbondings loop.
- [719](https://github.com/persistenceOne/pstake-native/pull/719) Fix afterEpoch hooks to take LiquidStake feature
Expand Down
116 changes: 68 additions & 48 deletions x/liquidstakeibc/keeper/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,61 +331,81 @@ func (k *Keeper) DoProcessMaturedUndelegations(ctx sdk.Context, hc *types.HostCh
}

func (k *Keeper) DoRedeemLSMTokens(ctx sdk.Context, hc *types.HostChain) {
// generate the ICA messages
messages := make([]proto.Message, 0)
deposits := k.GetRedeemableLSMDeposits(ctx, hc.ChainId)
for _, deposit := range deposits {
messages = append(
messages,
&stakingtypes.MsgRedeemTokensForShares{
DelegatorAddress: hc.DelegationAccount.Address,
Amount: sdk.NewCoin(deposit.Denom, deposit.Shares.TruncateInt()),
},
)
}

if len(messages) == 0 {
return
}
// generate the ICA messages
messagesChunks := make([][]proto.Message, 0)
depositsChunks := make([][]*types.LSMDeposit, 0)
for i := 0; i < len(deposits); i += types.ICAMessagesChunkSize {
end := i + types.ICAMessagesChunkSize

// avoid slicing past the deposits length
if end > len(deposits) {
end = len(deposits)
}

// execute the ICA transaction
sequenceID, err := k.GenerateAndExecuteICATx(
ctx,
hc.ConnectionId,
hc.DelegationAccount.Owner,
messages,
)
if err != nil {
k.Logger(ctx).Error("could not send ICA untokenize tx", "host_chain", hc.ChainId)
return
// create a redeem message for each deposit in the current chunk
depositsChunk := deposits[i:end]
messagesChunk := make([]proto.Message, 0)
for _, deposit := range depositsChunk {
messagesChunk = append(
messagesChunk,
&stakingtypes.MsgRedeemTokensForShares{
DelegatorAddress: hc.DelegationAccount.Address,
Amount: sdk.NewCoin(deposit.Denom, deposit.Shares.TruncateInt()),
},
)
}

// save both chunks in the respective arrays
messagesChunks = append(messagesChunks, messagesChunk)
depositsChunks = append(depositsChunks, depositsChunk)
}

// update the deposits state and add the IBC sequence
k.UpdateLSMDepositsStateAndSequence(
ctx,
deposits,
types.LSMDeposit_DEPOSIT_UNTOKENIZING,
sequenceID,
)
for i, messagesChunk := range messagesChunks {
if len(messagesChunk) == 0 {
continue
}

k.Logger(ctx).Info(
fmt.Sprintf("Redeeming %v deposits.", len(deposits)),
"host chain",
hc.ChainId,
"sequence-id",
sequenceID,
)
// execute the ICA transaction
sequenceID, err := k.GenerateAndExecuteICATx(
ctx,
hc.ConnectionId,
hc.DelegationAccount.Owner,
messagesChunk,
)
if err != nil {
k.Logger(ctx).Error("could not send ICA untokenize tx", "host_chain", hc.ChainId)
return
}

// emit the untokenize event
encMsgs, _ := json.Marshal(&messages)
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeRedeemTokensForShares,
sdk.NewAttribute(types.AttributeChainID, hc.ChainId),
sdk.NewAttribute(types.AttributeICAMessages, base64.StdEncoding.EncodeToString(encMsgs)),
sdk.NewAttribute(types.AttributeIBCSequenceID, sequenceID),
),
)
// update the deposits state and add the IBC sequence
k.UpdateLSMDepositsStateAndSequence(
ctx,
depositsChunks[i],
types.LSMDeposit_DEPOSIT_UNTOKENIZING,
sequenceID,
)

k.Logger(ctx).Info(
fmt.Sprintf("Redeeming %v deposits.", len(depositsChunks[i])),
"host chain",
hc.ChainId,
"sequence-id",
sequenceID,
)

// emit the untokenize event
encMsgs, _ := json.Marshal(&messagesChunks[i])
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeRedeemTokensForShares,
sdk.NewAttribute(types.AttributeChainID, hc.ChainId),
sdk.NewAttribute(types.AttributeICAMessages, base64.StdEncoding.EncodeToString(encMsgs)),
sdk.NewAttribute(types.AttributeIBCSequenceID, sequenceID),
),
)
}
}

func (k *Keeper) DoDeleteRedelegationTxs(ctx sdk.Context) {
Expand Down
2 changes: 2 additions & 0 deletions x/liquidstakeibc/types/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ const (

ICATimeoutTimestamp = 120 * time.Minute

ICAMessagesChunkSize = 10

IBCPrefix = transfertypes.DenomPrefix + "/"

UnbondingStateEpochLimit = 4
Expand Down

0 comments on commit 7d81888

Please sign in to comment.