mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-24 23:35:19 +00:00
feat(x/precisebank): Emit events for send/mint/burn (#1955)
Emits the **total** akava amount for both ukava and akava send/mint/burns. If both akava,ukava are sent (not possible via x/evm nor cosmos messages but still an edge case), then the sum is emitted. No other denoms are emitted by x/precisebank as they will be emitted by the underlying x/bank
This commit is contained in:
parent
2d07988994
commit
60a8073574
@ -8,6 +8,7 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
"github.com/kava-labs/kava/x/precisebank/types"
|
||||
)
|
||||
|
||||
@ -52,12 +53,23 @@ func (k Keeper) BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) err
|
||||
}
|
||||
}
|
||||
|
||||
// No more processing required if no ExtendedCoinDenom
|
||||
if extendedAmount.IsZero() {
|
||||
// Only burn extended coin if the amount is positive
|
||||
if extendedAmount.IsPositive() {
|
||||
if err := k.burnExtendedCoin(ctx, moduleName, extendedAmount); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
fullEmissionCoin := types.SumExtendedCoin(amt)
|
||||
if fullEmissionCoin.IsZero() {
|
||||
return nil
|
||||
}
|
||||
|
||||
return k.burnExtendedCoin(ctx, moduleName, extendedAmount)
|
||||
ctx.EventManager().EmitEvent(
|
||||
banktypes.NewCoinBurnEvent(acc.GetAddress(), sdk.NewCoins(fullEmissionCoin)),
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// burnExtendedCoin burns the fractional amount of the ExtendedCoinDenom from the module account.
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
sdkmath "cosmossdk.io/math"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"
|
||||
"github.com/kava-labs/kava/x/precisebank/keeper"
|
||||
"github.com/kava-labs/kava/x/precisebank/testutil"
|
||||
@ -209,6 +210,28 @@ func (suite *burnIntegrationTestSuite) TestBurnCoins() {
|
||||
res, stop := allInvariantsFn(suite.Ctx)
|
||||
suite.Require().False(stop, "invariant should not be broken")
|
||||
suite.Require().Empty(res, "unexpected invariant message: %s", res)
|
||||
|
||||
intCoinAmt := tt.burnCoins.AmountOf(types.IntegerCoinDenom).
|
||||
Mul(types.ConversionFactor())
|
||||
|
||||
fraCoinAmt := tt.burnCoins.AmountOf(types.ExtendedCoinDenom)
|
||||
|
||||
totalExtCoinAmt := intCoinAmt.Add(fraCoinAmt)
|
||||
|
||||
events := suite.Ctx.EventManager().Events()
|
||||
extendedEvent := banktypes.NewCoinBurnEvent(
|
||||
recipientAddr,
|
||||
sdk.NewCoins(sdk.NewCoin(
|
||||
types.ExtendedCoinDenom,
|
||||
totalExtCoinAmt,
|
||||
)),
|
||||
)
|
||||
|
||||
if totalExtCoinAmt.IsZero() {
|
||||
suite.Require().NotContains(events, extendedEvent)
|
||||
} else {
|
||||
suite.Require().Contains(events, extendedEvent)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
|
||||
"github.com/kava-labs/kava/x/precisebank/types"
|
||||
)
|
||||
@ -55,12 +56,23 @@ func (k Keeper) MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) err
|
||||
}
|
||||
}
|
||||
|
||||
// No more processing required if no ExtendedCoinDenom
|
||||
if extendedAmount.IsZero() {
|
||||
// Only mint extended coin if the amount is positive
|
||||
if extendedAmount.IsPositive() {
|
||||
if err := k.mintExtendedCoin(ctx, moduleName, extendedAmount); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
fullEmissionCoin := types.SumExtendedCoin(amt)
|
||||
if fullEmissionCoin.IsZero() {
|
||||
return nil
|
||||
}
|
||||
|
||||
return k.mintExtendedCoin(ctx, moduleName, extendedAmount)
|
||||
ctx.EventManager().EmitEvent(
|
||||
banktypes.NewCoinMintEvent(acc.GetAddress(), sdk.NewCoins(fullEmissionCoin)),
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// mintExtendedCoin manages the minting of only extended coins. This also
|
||||
|
@ -334,6 +334,30 @@ func (suite *mintIntegrationTestSuite) TestMintCoins() {
|
||||
allInvariantsFn := keeper.AllInvariants(suite.Keeper)
|
||||
msg, stop := allInvariantsFn(suite.Ctx)
|
||||
suite.Require().Falsef(stop, "invariant should not be broken: %s", msg)
|
||||
|
||||
// Get event for minted coins
|
||||
intCoinAmt := mt.mintAmount.AmountOf(types.IntegerCoinDenom).
|
||||
Mul(types.ConversionFactor())
|
||||
|
||||
fraCoinAmt := mt.mintAmount.AmountOf(types.ExtendedCoinDenom)
|
||||
|
||||
totalExtCoinAmt := intCoinAmt.Add(fraCoinAmt)
|
||||
|
||||
// Check for mint event
|
||||
events := suite.Ctx.EventManager().Events()
|
||||
extendedEvent := banktypes.NewCoinMintEvent(
|
||||
recipientAddr,
|
||||
sdk.NewCoins(sdk.NewCoin(
|
||||
types.ExtendedCoinDenom,
|
||||
totalExtCoinAmt,
|
||||
)),
|
||||
)
|
||||
|
||||
if totalExtCoinAmt.IsZero() {
|
||||
suite.Require().NotContains(events, extendedEvent)
|
||||
} else {
|
||||
suite.Require().Contains(events, extendedEvent)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -8,15 +8,18 @@ import (
|
||||
sdkmath "cosmossdk.io/math"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
"github.com/kava-labs/kava/x/precisebank/types"
|
||||
)
|
||||
|
||||
// IsSendEnabledCoins uses the parent x/bank keeper to check the coins provided
|
||||
// and returns an ErrSendDisabled if any of the coins are not configured for
|
||||
// sending. Returns nil if sending is enabled for all provided coin
|
||||
// sending. Returns nil if sending is enabled for all provided coin.
|
||||
// Note: This method is not used directly by x/evm, but is still required as
|
||||
// part of authtypes.BankKeeper. x/evm uses auth methods that require this
|
||||
// interface.
|
||||
func (k Keeper) IsSendEnabledCoins(ctx sdk.Context, coins ...sdk.Coin) error {
|
||||
// TODO: This does not actually seem to be used by x/evm, so it should be
|
||||
// removed from the expected_interface in x/evm.
|
||||
// Simply pass through to x/bank
|
||||
return k.bk.IsSendEnabledCoins(ctx, coins...)
|
||||
}
|
||||
|
||||
@ -52,13 +55,35 @@ func (k Keeper) SendCoins(
|
||||
}
|
||||
}
|
||||
|
||||
// If there is no extended coin amount, we are done
|
||||
if extendedCoinAmount.IsZero() {
|
||||
// Send the extended coin amount through x/precisebank
|
||||
if extendedCoinAmount.IsPositive() {
|
||||
if err := k.sendExtendedCoins(ctx, from, to, extendedCoinAmount); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Get a full extended coin amount (passthrough integer + fractional) ONLY
|
||||
// for event attributes.
|
||||
fullEmissionCoin := types.SumExtendedCoin(amt)
|
||||
|
||||
// If no passthrough integer nor fractional coins, then no event emission.
|
||||
// We also want to emit the event with the whole equivalent extended coin
|
||||
// if only integer coins are sent.
|
||||
if fullEmissionCoin.IsZero() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Send the extended coin amount through x/precisebank
|
||||
return k.sendExtendedCoins(ctx, from, to, extendedCoinAmount)
|
||||
// Emit transfer event of extended denom for the FULL equivalent value.
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
banktypes.EventTypeTransfer,
|
||||
sdk.NewAttribute(banktypes.AttributeKeyRecipient, to.String()),
|
||||
sdk.NewAttribute(banktypes.AttributeKeySender, from.String()),
|
||||
sdk.NewAttribute(sdk.AttributeKeyAmount, fullEmissionCoin.String()),
|
||||
),
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// sendExtendedCoins transfers amt extended coins from a sending account to a
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"testing"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
|
||||
"github.com/kava-labs/kava/app"
|
||||
"github.com/kava-labs/kava/x/precisebank/keeper"
|
||||
@ -400,25 +401,25 @@ func (suite *sendIntegrationTestSuite) TestSendCoins() {
|
||||
// Convert send amount coins to extended coins. i.e. if send coins
|
||||
// includes ukava, convert it so that its the equivalent akava
|
||||
// amount so its easier to compare. Compare extended coins only.
|
||||
sendAmountExtended := tt.giveAmt
|
||||
sendAmountFullExtended := tt.giveAmt
|
||||
sendAmountInteger := tt.giveAmt.AmountOf(types.IntegerCoinDenom)
|
||||
if !sendAmountInteger.IsZero() {
|
||||
integerCoin := sdk.NewCoin(types.IntegerCoinDenom, sendAmountInteger)
|
||||
sendAmountExtended = sendAmountExtended.Sub(integerCoin)
|
||||
sendAmountFullExtended = sendAmountFullExtended.Sub(integerCoin)
|
||||
|
||||
// Add equivalent extended coin
|
||||
extendedCoinAmount := sendAmountInteger.Mul(types.ConversionFactor())
|
||||
extendedCoin := sdk.NewCoin(types.ExtendedCoinDenom, extendedCoinAmount)
|
||||
sendAmountExtended = sendAmountExtended.Add(extendedCoin)
|
||||
sendAmountFullExtended = sendAmountFullExtended.Add(extendedCoin)
|
||||
}
|
||||
|
||||
suite.Require().Equal(
|
||||
senderBalBefore.Sub(sendAmountExtended...),
|
||||
senderBalBefore.Sub(sendAmountFullExtended...),
|
||||
senderBalAfter,
|
||||
)
|
||||
|
||||
suite.Require().Equal(
|
||||
recipientBalBefore.Add(sendAmountExtended...),
|
||||
recipientBalBefore.Add(sendAmountFullExtended...),
|
||||
recipientBalAfter,
|
||||
)
|
||||
|
||||
@ -426,6 +427,28 @@ func (suite *sendIntegrationTestSuite) TestSendCoins() {
|
||||
res, stop := invariantFn(suite.Ctx)
|
||||
suite.Require().False(stop, "invariants should not stop")
|
||||
suite.Require().Empty(res, "invariants should not return any messages")
|
||||
|
||||
// Check events
|
||||
|
||||
// FULL akava equivalent, including ukava only/mixed sends
|
||||
sendExtendedAmount := sdk.NewCoin(
|
||||
types.ExtendedCoinDenom,
|
||||
sendAmountFullExtended.AmountOf(types.ExtendedCoinDenom),
|
||||
)
|
||||
|
||||
// No extra events if not sending akava
|
||||
if sendExtendedAmount.IsZero() {
|
||||
return
|
||||
}
|
||||
|
||||
extendedEvent := sdk.NewEvent(
|
||||
banktypes.EventTypeTransfer,
|
||||
sdk.NewAttribute(banktypes.AttributeKeyRecipient, recipient.String()),
|
||||
sdk.NewAttribute(banktypes.AttributeKeySender, sender.String()),
|
||||
sdk.NewAttribute(sdk.AttributeKeyAmount, sendExtendedAmount.String()),
|
||||
)
|
||||
|
||||
suite.Require().Contains(suite.Ctx.EventManager().Events(), extendedEvent)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
25
x/precisebank/types/extended_balance.go
Normal file
25
x/precisebank/types/extended_balance.go
Normal file
@ -0,0 +1,25 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// SumExtendedCoin returns a sdk.Coin of extended coin denomination
|
||||
// with all integer and fractional amounts combined. e.g. if amount contains
|
||||
// both coins of integer denom and extended denom, this will return the total
|
||||
// amount in extended coins. This is intended to get the full value to emit in
|
||||
// events.
|
||||
func SumExtendedCoin(amt sdk.Coins) sdk.Coin {
|
||||
// ukava converted to akava
|
||||
integerAmount := amt.AmountOf(IntegerCoinDenom).Mul(conversionFactor)
|
||||
// akava as is
|
||||
extendedAmount := amt.AmountOf(ExtendedCoinDenom)
|
||||
|
||||
// total of ukava and akava amounts
|
||||
fullEmissionAmount := integerAmount.Add(extendedAmount)
|
||||
|
||||
return sdk.NewCoin(
|
||||
ExtendedCoinDenom,
|
||||
fullEmissionAmount,
|
||||
)
|
||||
}
|
48
x/precisebank/types/extended_balance_test.go
Normal file
48
x/precisebank/types/extended_balance_test.go
Normal file
@ -0,0 +1,48 @@
|
||||
package types_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/kava-labs/kava/x/precisebank/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestSumExtendedCoin(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
amt sdk.Coins
|
||||
want sdk.Coin
|
||||
}{
|
||||
{
|
||||
"empty",
|
||||
sdk.NewCoins(),
|
||||
sdk.NewCoin(types.ExtendedCoinDenom, sdk.ZeroInt()),
|
||||
},
|
||||
{
|
||||
"only integer",
|
||||
sdk.NewCoins(sdk.NewInt64Coin(types.IntegerCoinDenom, 100)),
|
||||
sdk.NewCoin(types.ExtendedCoinDenom, types.ConversionFactor().MulRaw(100)),
|
||||
},
|
||||
{
|
||||
"only extended",
|
||||
sdk.NewCoins(sdk.NewInt64Coin(types.ExtendedCoinDenom, 100)),
|
||||
sdk.NewCoin(types.ExtendedCoinDenom, sdk.NewInt(100)),
|
||||
},
|
||||
{
|
||||
"integer and extended",
|
||||
sdk.NewCoins(
|
||||
sdk.NewInt64Coin(types.IntegerCoinDenom, 100),
|
||||
sdk.NewInt64Coin(types.ExtendedCoinDenom, 100),
|
||||
),
|
||||
sdk.NewCoin(types.ExtendedCoinDenom, types.ConversionFactor().MulRaw(100).AddRaw(100)),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
extVal := types.SumExtendedCoin(tt.amt)
|
||||
require.Equal(t, tt.want, extVal)
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user