Commit e8ec1083 authored by Son of Odin's avatar Son of Odin

[bugfix] slash ygg, migrate, and ragnarok memo when appropriate

parent d496c485
Pipeline #130142038 failed with stages
in 22 minutes and 25 seconds
......@@ -60,6 +60,17 @@ func (h MigrateHandler) handle(ctx sdk.Context, msg MsgMigrate, version semver.V
return errBadVersion.Result()
}
func (h MigrateHandler) slash(ctx sdk.Context, tx ObservedTx) error {
var returnErr error
for _, c := range tx.Tx.Coins {
if err := slashNodeAccount(ctx, h.keeper, tx.ObservedPubKey, c.Asset, c.Amount); err != nil {
ctx.Logger().Error("fail to slash account", "error", err)
returnErr = err
}
}
return returnErr
}
func (h MigrateHandler) handleV1(ctx sdk.Context, msg MsgMigrate) sdk.Result {
// update txOut record with our TxID that sent funds out of the pool
txOut, err := h.keeper.GetTxOut(ctx, msg.BlockHeight)
......@@ -67,14 +78,8 @@ func (h MigrateHandler) handleV1(ctx sdk.Context, msg MsgMigrate) sdk.Result {
ctx.Logger().Error("unable to get txOut record", "error", err)
return sdk.ErrUnknownRequest(err.Error()).Result()
}
if txOut.IsEmpty() {
return sdk.Result{
Code: sdk.CodeOK,
Codespace: DefaultCodespace,
}
}
hasChanged := false
shouldSlash := true
for i, tx := range txOut.TxArray {
// migrate is the memo used by thorchain to identify fund migration between asgard vault.
// it use migrate:{block height} to mark a tx out caused by vault rotation
......@@ -85,22 +90,25 @@ func (h MigrateHandler) handleV1(ctx sdk.Context, msg MsgMigrate) sdk.Result {
msg.Tx.Tx.Coins.Contains(tx.Coin) &&
tx.ToAddress.Equals(msg.Tx.Tx.ToAddress) &&
fromAddress.Equals(msg.Tx.Tx.FromAddress) {
txOut.TxArray[i].OutHash = msg.Tx.Tx.ID
hasChanged = true
shouldSlash = false
if err := h.keeper.SetTxOut(ctx, txOut); nil != err {
ctx.Logger().Error("fail to save tx out", "error", err)
return sdk.ErrInternal("fail to save tx out").Result()
}
break
}
}
if !hasChanged {
return sdk.Result{
Code: sdk.CodeOK,
Codespace: DefaultCodespace,
if shouldSlash {
if err := h.slash(ctx, msg.Tx); err != nil {
return sdk.ErrInternal("fail to slash account").Result()
}
}
if err := h.keeper.SetTxOut(ctx, txOut); nil != err {
ctx.Logger().Error("fail to save tx out", "error", err)
return sdk.ErrInternal("fail to save tx out").Result()
}
h.keeper.SetLastSignedHeight(ctx, msg.BlockHeight)
return sdk.Result{
......
......@@ -60,6 +60,17 @@ func (h RagnarokHandler) handle(ctx sdk.Context, msg MsgRagnarok, version semver
return errBadVersion.Result()
}
func (h RagnarokHandler) slash(ctx sdk.Context, tx ObservedTx) error {
var returnErr error
for _, c := range tx.Tx.Coins {
if err := slashNodeAccount(ctx, h.keeper, tx.ObservedPubKey, c.Asset, c.Amount); err != nil {
ctx.Logger().Error("fail to slash account", "error", err)
returnErr = err
}
}
return returnErr
}
func (h RagnarokHandler) handleV1(ctx sdk.Context, msg MsgRagnarok) sdk.Result {
// update txOut record with our TxID that sent funds out of the pool
txOut, err := h.keeper.GetTxOut(ctx, msg.BlockHeight)
......@@ -67,14 +78,8 @@ func (h RagnarokHandler) handleV1(ctx sdk.Context, msg MsgRagnarok) sdk.Result {
ctx.Logger().Error("unable to get txOut record", "error", err)
return sdk.ErrUnknownRequest(err.Error()).Result()
}
if txOut.IsEmpty() {
return sdk.Result{
Code: sdk.CodeOK,
Codespace: DefaultCodespace,
}
}
hasChanged := false
shouldSlash := true
for i, tx := range txOut.TxArray {
// ragnarok is the memo used by thorchain to identify fund returns to
// bonders, LPs, and reserve contributors.
......@@ -87,22 +92,24 @@ func (h RagnarokHandler) handleV1(ctx sdk.Context, msg MsgRagnarok) sdk.Result {
msg.Tx.Tx.Coins.Contains(tx.Coin) &&
tx.ToAddress.Equals(msg.Tx.Tx.ToAddress) &&
fromAddress.Equals(msg.Tx.Tx.FromAddress) {
txOut.TxArray[i].OutHash = msg.Tx.Tx.ID
hasChanged = true
shouldSlash = false
if err := h.keeper.SetTxOut(ctx, txOut); nil != err {
ctx.Logger().Error("fail to save tx out", "error", err)
return sdk.ErrInternal("fail to save tx out").Result()
}
break
}
}
if !hasChanged {
return sdk.Result{
Code: sdk.CodeOK,
Codespace: DefaultCodespace,
if shouldSlash {
if err := h.slash(ctx, msg.Tx); err != nil {
return sdk.ErrInternal("fail to slash account").Result()
}
}
if err := h.keeper.SetTxOut(ctx, txOut); nil != err {
ctx.Logger().Error("fail to save tx out", "error", err)
return sdk.ErrInternal("fail to save tx out").Result()
}
h.keeper.SetLastSignedHeight(ctx, msg.BlockHeight)
return sdk.Result{
......
......@@ -75,6 +75,17 @@ func (h YggdrasilHandler) handle(ctx sdk.Context, msg MsgYggdrasil, version semv
}
}
func (h YggdrasilHandler) slash(ctx sdk.Context, pk common.PubKey, coins common.Coins) error {
var returnErr error
for _, c := range coins {
if err := slashNodeAccount(ctx, h.keeper, pk, c.Asset, c.Amount); err != nil {
ctx.Logger().Error("fail to slash account", "error", err)
returnErr = err
}
}
return returnErr
}
func (h YggdrasilHandler) handleV1(ctx sdk.Context, msg MsgYggdrasil, version semver.Version) sdk.Result {
// update txOut record with our TxID that sent funds out of the pool
txOut, err := h.keeper.GetTxOut(ctx, msg.BlockHeight)
......@@ -83,6 +94,7 @@ func (h YggdrasilHandler) handleV1(ctx sdk.Context, msg MsgYggdrasil, version se
return sdk.ErrUnknownRequest(err.Error()).Result()
}
shouldSlash := true
for i, tx := range txOut.TxArray {
// yggdrasil is the memo used by thorchain to identify fund migration
// to a yggdrasil vault.
......@@ -100,15 +112,24 @@ func (h YggdrasilHandler) handleV1(ctx sdk.Context, msg MsgYggdrasil, version se
if msg.AddFunds && !msg.Tx.Coins.Contains(tx.Coin) {
continue
}
txOut.TxArray[i].OutHash = msg.Tx.ID
shouldSlash = false
if err := h.keeper.SetTxOut(ctx, txOut); nil != err {
ctx.Logger().Error("fail to save tx out", "error", err)
}
h.keeper.SetLastSignedHeight(ctx, msg.BlockHeight)
break
}
}
if shouldSlash {
if err := h.slash(ctx, msg.PubKey, msg.Tx.Coins); err != nil {
return sdk.ErrInternal("fail to slash account").Result()
}
}
vault, err := h.keeper.GetVault(ctx, msg.PubKey)
if err != nil && !stdErrors.Is(err, ErrVaultNotFound) {
ctx.Logger().Error("fail to get yggdrasil", "error", err)
......@@ -119,6 +140,8 @@ func (h YggdrasilHandler) handleV1(ctx sdk.Context, msg MsgYggdrasil, version se
vault.Type = YggdrasilVault
}
h.keeper.SetLastSignedHeight(ctx, msg.BlockHeight)
if msg.AddFunds {
return h.handleYggdrasilFund(ctx, msg, vault)
}
......
......@@ -251,11 +251,10 @@ func (s *HandlerYggdrasilSuite) TestYggdrasilHandler(c *C) {
},
expectedResult: sdk.CodeOK,
validator: func(helper yggdrasilHandlerTestHelper, msg sdk.Msg, result sdk.Result, c *C) {
beforeBond := helper.nodeAccount.Bond
slashAmount := sdk.NewUint(common.One).MulUint64(3)
expectedBond := helper.nodeAccount.Bond.Sub(sdk.NewUint(603787879))
na, err := helper.keeper.GetNodeAccount(helper.ctx, helper.nodeAccount.NodeAddress)
c.Assert(err, IsNil)
c.Assert(na.Bond.Equal(common.SafeSub(beforeBond, slashAmount)), Equals, true)
c.Assert(na.Bond.Equal(expectedBond), Equals, true, Commentf("%d/%d", na.Bond.Uint64(), expectedBond.Uint64()))
},
},
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment