mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-04-04 15:55:23 +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
	 drklee3
						drklee3