From 4296f2e930a65ffe9397b928722874f5412f739f Mon Sep 17 00:00:00 2001 From: Kay Date: Mon, 5 Feb 2024 16:20:23 +0000 Subject: [PATCH] feat(engine): adding validator reward calculate method (discord added) --- discord/commands.go | 25 ++++++++++++++++++++++--- discord/embeds.go | 8 ++++++++ discord/handlers.go | 37 ++++++++++++++++++++++++++++++++++++- engine/engine.go | 25 +++++++++++++++++++++++++ engine/interface.go | 1 + engine/run.go | 25 +++++++++++++++++++++++-- 6 files changed, 115 insertions(+), 6 deletions(-) diff --git a/discord/commands.go b/discord/commands.go index e348b468..ab764867 100644 --- a/discord/commands.go +++ b/discord/commands.go @@ -49,6 +49,24 @@ var commands = []*discordgo.ApplicationCommand{ }, }, }, + { + Name: "reward-calc", + Description: "calculates how much PAC coins you will earn in a (day/month/year) based on your stake.", + Options: []*discordgo.ApplicationCommandOption{ + { + Type: discordgo.ApplicationCommandOptionString, + Name: "stake", + Description: "your validator stake amount", + Required: true, + }, + { + Type: discordgo.ApplicationCommandOptionString, + Name: "time", + Description: "in a day/month/year (default is a day)", + Required: false, + }, + }, + }, { Name: "network-health", Description: "network health status", @@ -58,8 +76,8 @@ var commands = []*discordgo.ApplicationCommand{ Description: "status of The Pactus network", }, { - Name: "bot-wallet", - Description: "The RoboPac wallet address and balance", + Name: "wallet", + Description: "The RoboPac wallet info", }, { Name: "claim-status", @@ -78,6 +96,7 @@ var commandHandlers = map[string]func(*DiscordBot, *discordgo.Session, *discordg "node-info": nodeInfoCommandHandler, "network-health": networkHealthCommandHandler, "network-status": networkStatusCommandHandler, - "bot-wallet": botWalletCommandHandler, + "wallet": walletCommandHandler, "claim-status": claimStatusCommandHandler, + "reward-calc": rewardCalcCommandHandler, } diff --git a/discord/embeds.go b/discord/embeds.go index 5177cc64..6cea8daf 100644 --- a/discord/embeds.go +++ b/discord/embeds.go @@ -83,6 +83,14 @@ func claimStatusEmbed(s *discordgo.Session, i *discordgo.InteractionCreate, resu } } +func rewardCalcEmbed(s *discordgo.Session, i *discordgo.InteractionCreate, result string) *discordgo.MessageEmbed { + return &discordgo.MessageEmbed{ + Title: "Vlidator reward calculation🧮", + Description: result, + Color: PACTUS, + } +} + func errorEmbedMessage(reason string) *discordgo.MessageEmbed { return &discordgo.MessageEmbed{ Title: "Error", diff --git a/discord/handlers.go b/discord/handlers.go index 0a9ec1cf..43a653cc 100644 --- a/discord/handlers.go +++ b/discord/handlers.go @@ -214,7 +214,7 @@ func networkStatusCommandHandler(db *DiscordBot, s *discordgo.Session, i *discor _ = s.InteractionRespond(i.Interaction, response) } -func botWalletCommandHandler(db *DiscordBot, s *discordgo.Session, i *discordgo.InteractionCreate) { +func walletCommandHandler(db *DiscordBot, s *discordgo.Session, i *discordgo.InteractionCreate) { if !checkMessage(i, s, db.GuildID, i.Member.User.ID) { return } @@ -249,3 +249,38 @@ func claimStatusCommandHandler(db *DiscordBot, s *discordgo.Session, i *discordg _ = s.InteractionRespond(i.Interaction, response) } + +func rewardCalcCommandHandler(db *DiscordBot, s *discordgo.Session, i *discordgo.InteractionCreate) { + if !checkMessage(i, s, db.GuildID, i.Member.User.ID) { + return + } + + stake := i.ApplicationCommandData().Options[0].StringValue() + time := i.ApplicationCommandData().Options[1].StringValue() + + result, err := db.BotEngine.Run(fmt.Sprintf("calc-reward %v %v", stake, time)) + if err != nil { + errorEmbed := errorEmbedMessage(err.Error()) + + response := &discordgo.InteractionResponse{ + Type: discordgo.InteractionResponseChannelMessageWithSource, + Data: &discordgo.InteractionResponseData{ + Embeds: []*discordgo.MessageEmbed{errorEmbed}, + }, + } + + _ = s.InteractionRespond(i.Interaction, response) + + return + } + + embed := rewardCalcEmbed(s, i, result) + response := &discordgo.InteractionResponse{ + Type: discordgo.InteractionResponseChannelMessageWithSource, + Data: &discordgo.InteractionResponseData{ + Embeds: []*discordgo.MessageEmbed{embed}, + }, + } + + _ = s.InteractionRespond(i.Interaction, response) +} diff --git a/engine/engine.go b/engine/engine.go index c9ecf62d..8a616cd4 100644 --- a/engine/engine.go +++ b/engine/engine.go @@ -12,6 +12,7 @@ import ( "github.com/kehiy/RoboPac/utils" "github.com/kehiy/RoboPac/wallet" "github.com/libp2p/go-libp2p/core/peer" + putils "github.com/pactus-project/pactus/util" ) type BotEngine struct { @@ -246,6 +247,30 @@ func (be *BotEngine) ClaimStatus() (int64, int64, int64, int64) { return be.Store.Status() } +func (be *BotEngine) RewardCalculate(stake int64, t string) (int64, string, int64, error) { + var blocks int64 + time := t + switch t { + case "day": + blocks = 8640 + case "month": + blocks = 259200 + case "year": + blocks = 3110400 + default: + blocks = 8640 + time = "day" + } + + bi, err := be.Cm.GetBlockchainInfo() + if err != nil { + return 0, "", 0, nil + } + + reward := (stake * int64(blocks)) / int64(putils.ChangeToCoin(bi.TotalPower)) + return reward, time, bi.TotalPower, nil +} + func (be *BotEngine) Stop() { be.logger.Info("shutting bot engine down...") diff --git a/engine/interface.go b/engine/interface.go index 9279efdf..916f0bea 100644 --- a/engine/interface.go +++ b/engine/interface.go @@ -9,6 +9,7 @@ type IEngine interface { ClaimerInfo(discordID string) (*store.Claimer, error) Claim(discordID string, testnetAddr string, mainnetAddr string) (string, error) BotWallet() (string, int64) + RewardCalculate(int64, string) (int64, string, int64, error) Run(input string) (string, error) diff --git a/engine/run.go b/engine/run.go index 0ab63d06..f9c3dd79 100644 --- a/engine/run.go +++ b/engine/run.go @@ -2,6 +2,7 @@ package engine import ( "fmt" + "strconv" "strings" "github.com/pactus-project/pactus/util" @@ -13,8 +14,9 @@ const ( CmdNodeInfo = "node-info" //! CmdNetworkStatus = "network" //! CmdNetworkHealth = "network-health" //! - CmdBotWallet = "bot-wallet" //! + CmdBotWallet = "wallet" //! CmdClaimStatus = "claim-status" //! + CmdRewardCalc = "calc-reward" //! ) // The input is always string. @@ -98,7 +100,7 @@ func (be *BotEngine) Run(input string) (string, error) { return fmt.Sprintf("Network Name: %s\nConnected Peers: %v\n"+ "Validators Count: %v\nAccounts Count: %v\nCurrent Block Height: %v\nTotal Power: %v PAC's\nTotal Committee Power: %v PAC's\n"+ - "> Note📝: This info is from one random network node. Non-blockchain data may not be consistent.", + "\n> Note📝: This info is from one random network node. Non-blockchain data may not be consistent.", net.NetworkName, net.ConnectedPeersCount, net.ValidatorsCount, net.TotalAccounts, net.CurrentBlockHeight, util.ChangeToString(net.TotalNetworkPower), util.ChangeToString(net.TotalCommitteePower)), nil @@ -111,6 +113,25 @@ func (be *BotEngine) Run(input string) (string, error) { return fmt.Sprintf("Claimed rewards count: %v\nClaimed coins: %v PAC's\nNot-claimed rewards count: %v\nNot-claim coins: %v PAC's\n", claimed, util.ChangeToString(claimedAmount), notClaimed, util.ChangeToString(notClaimedAmount)), nil + case CmdRewardCalc: + if len(args) != 2 { + return "", fmt.Errorf("expected to have 2 arguments, but it received %d", len(args)) + } + + stake, err := strconv.Atoi(args[0]) + if err != nil { + return "", err + } + + reward, time, totalPower, err := be.RewardCalculate(int64(stake), args[1]) + if err != nil { + return "", err + } + + return fmt.Sprintf("You will get: %v :pac: reward, with %v stake 🔒 on your validator in one %s ⏰ with %v total power ⚡ of committee."+ + "\n\n> Note📝: This is an estimation not a 100 percent correct data and with increasing total power, validators and your stake amount this number will change.", + reward, stake, time, util.ChangeToString(totalPower)), nil + default: return "", fmt.Errorf("unknown command: %s", cmd) }