Skip to content

Commit

Permalink
feat: withdraw rewards and commission (#19)
Browse files Browse the repository at this point in the history
Co-authored-by: aleem1314 <aleem@vitwit.com>
  • Loading branch information
0xbala-k and aleem1314 authored Aug 11, 2023
1 parent 6577cfe commit 92d65dc
Show file tree
Hide file tree
Showing 13 changed files with 823 additions and 50 deletions.
72 changes: 72 additions & 0 deletions voting-bot/database/sqlite.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ type (
VoteOption string
}

rewardsCommission struct {
ChainID string
Denom string
ValAddr string
Rewards string
Commission string
Date string
}

Sqlitedb struct {
db *sql.DB
}
Expand Down Expand Up @@ -72,6 +81,11 @@ func (a *Sqlitedb) InitializeTables() error {
return err
}

_, err = a.db.Exec("CREATE TABLE IF NOT EXISTS rewards_commission (chainId VARCHAR, denom VARCHAR, valAddress VARCHAR, rewards VARCHAR, commission VARCHAR, date VARCHAR)")
if err != nil {
return err
}

_, err = a.db.Exec("ALTER TABLE keys ADD COLUMN authzStatus VARCHAR DEFAULT 'false'")
return err
}
Expand Down Expand Up @@ -154,6 +168,18 @@ func (a *Sqlitedb) AddLog(chainName, proposalTitle, proposalID, voteOption strin
return err
}

func (a *Sqlitedb) AddRewards(chainId, denom, valAddr, rewards, commission string) error {
stmt, err := a.db.Prepare("INSERT INTO rewards_commission(chainId, denom, valAddress, rewards, commission, date) values(?,?,?,?,?,?)")
if err != nil {
return err
}

defer stmt.Close()

_, err = stmt.Exec(chainId, denom, valAddr, rewards, commission, time.Now().Format("2006-01-02"))
return err
}

// Checks whether the validator already exists in the database
func (s *Sqlitedb) HasValidator(validatorAddress string) bool {
stmt, err := s.db.Prepare("SELECT EXISTS(SELECT 1 FROM validators WHERE address = ?)")
Expand Down Expand Up @@ -330,3 +356,49 @@ func (a *Sqlitedb) GetVoteLogs(chainName, startDate, endDate string) ([]voteLogs

return k, nil
}

// Gets required data regarding rewards
func (a *Sqlitedb) GetRewards(chainId, date string) ([]rewardsCommission, error) {
log.Printf("Fetching rewards...")
var k []rewardsCommission

if date != "" {
query := "SELECT chainId, denom, valAddress, rewards, commission, date FROM rewards_commission WHERE chainId = ? AND date = ? "
rows, err := a.db.Query(query, chainId, date)
if err != nil {
return []rewardsCommission{}, err
}
defer rows.Close()

for rows.Next() {
var data rewardsCommission
if err := rows.Scan(&data.ChainID, &data.Denom, &data.ValAddr, &data.Rewards, &data.Commission, &data.Date); err != nil {
return k, err
}
k = append(k, data)
}
if err := rows.Err(); err != nil {
return k, err
}
} else {
query := "SELECT chainId, denom, valAddress, rewards, commission, date FROM rewards_commission WHERE chainId = ? "
rows, err := a.db.Query(query, chainId)
if err != nil {
return []rewardsCommission{}, err
}
defer rows.Close()

for rows.Next() {
var data rewardsCommission
if err := rows.Scan(&data.ChainID, &data.Denom, &data.ValAddr, &data.Rewards, &data.Commission, &data.Date); err != nil {
return k, err
}
k = append(k, data)
}
if err := rows.Err(); err != nil {
return k, err
}
}

return k, nil
}
2 changes: 2 additions & 0 deletions voting-bot/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ require (
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.1 // indirect
github.com/googleapis/gax-go/v2 v2.7.0 // indirect
github.com/gorilla/mux v1.8.0
github.com/gorilla/websocket v1.5.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
Expand All @@ -100,6 +101,7 @@ require (
github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/jmhodges/levigo v1.0.0 // indirect
github.com/joho/godotenv v1.5.1 // indirect
github.com/klauspost/compress v1.15.11 // indirect
github.com/leodido/go-urn v1.2.3 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
Expand Down
3 changes: 3 additions & 0 deletions voting-bot/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57Q
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
Expand Down Expand Up @@ -382,6 +383,8 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U=
github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
Expand Down
36 changes: 36 additions & 0 deletions voting-bot/main.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package main

import (
"encoding/json"
"fmt"
"net/http"
"sync"

"github.com/rs/zerolog"
"github.com/rs/zerolog/log"

"github.com/gorilla/mux"
"github.com/shomali11/slacker"
"github.com/vitwit/authz-apps/voting-bot/client"
"github.com/vitwit/authz-apps/voting-bot/config"
Expand All @@ -30,6 +33,16 @@ func main() {
}
}()

// Initialize the router
router := mux.NewRouter()

// Define REST API endpoints
router.HandleFunc("/rewards", getRewardsHandler(db)).Methods("GET")

// Start the server
logger.Info().Msg("Server started at http://localhost:8080")
log.Error().Err(http.ListenAndServe(":8080", router))

cfg, err := config.ReadConfigFromFile()
if err != nil {
logger.Error().Err(err)
Expand All @@ -50,3 +63,26 @@ func main() {
wg.Add(1)
wg.Wait()
}

// TODO: seperate file
func getRewardsHandler(db *database.Sqlitedb) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {

params := r.URL.Query()
chainId := params.Get("id")
date := params.Get("date")

rewards, err := db.GetRewards(chainId, date)
if err != nil {
http.Error(w, fmt.Errorf("Error while getting rewards: %w", err).Error(), http.StatusBadRequest)
return
}

w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(rewards)
if err != nil {
http.Error(w, fmt.Errorf("Error while encoding rewards: %w", err).Error(), http.StatusInternalServerError)
return
}
}
}
57 changes: 9 additions & 48 deletions voting-bot/targets/authz.go
Original file line number Diff line number Diff line change
@@ -1,47 +1,15 @@
package targets

import (
"encoding/json"
"io/ioutil"
"log"
"net/http"

"github.com/vitwit/authz-apps/voting-bot/endpoints"
"github.com/vitwit/authz-apps/voting-bot/types"
"github.com/vitwit/authz-apps/voting-bot/utils"
)

func getAuthzGrants(endpoint string) ([]interface{}, error) {
response, err := http.Get(endpoint)
if err != nil {
return nil, err
}
defer response.Body.Close()

body, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Println("Failed to read response body:", err)
return nil, err
}
var jsonData map[string]interface{}
err = json.Unmarshal(body, &jsonData)
if err != nil {
log.Println("Failed to parse JSON data:", err)
return nil, err
}

grantsInterface, ok := jsonData["grants"]
if !ok || grantsInterface == nil {
// handle the case when "grants" is not present or nil
return []interface{}(nil), nil
}

grants, ok := grantsInterface.([]interface{})
if !ok {
// handle the case when "grants" is not a slice of interfaces
return []interface{}(nil), nil
}
return grants, nil
}
const MSG_VOTE_TYPEURL_V1BETA1 = "/cosmos.gov.v1beta1.MsgVote"
const MSG_VOTE_TYPEURL_V1 = "/cosmos.gov.v1.MsgVote"

// SyncAuthzStatus iterates over all validators account and update
// authz grant status
Expand All @@ -64,35 +32,28 @@ func SyncAuthzStatus(ctx types.Context) error {
for _, val := range validators {
if val.ChainName == key.ChainName {

accAddr, err := convertValAddrToAccAddr(ctx, val.Address, key.ChainName)
granter, err := convertValAddrToAccAddr(ctx, val.Address, key.ChainName)
if err != nil {
return err
}

ops := types.HTTPOptions{
Endpoint: validEndpoint + "/cosmos/authz/v1beta1/grants?granter=" + accAddr + "&grantee=" + key.KeyAddress + "&msg_url_type=/cosmos.gov.v1beta1.MsgVote",
Method: http.MethodGet,
}
g1, err := getAuthzGrants(ops.Endpoint)
hasAuthz, err := utils.HasAuthzGrant(validEndpoint, granter, key.KeyAddress, MSG_VOTE_TYPEURL_V1BETA1)
if err != nil {
return err
}
if len(g1) > 0 {

if hasAuthz {
if err := ctx.Database().UpdateAuthzStatus("true", key.KeyAddress); err != nil {
return err
}
}

ops = types.HTTPOptions{
Endpoint: validEndpoint + "/cosmos/authz/v1beta1/grants?granter=" + accAddr + "&grantee=" + key.KeyAddress + "&msg_url_type=/cosmos.gov.v1.MsgVote",
Method: http.MethodGet,
}
g2, err := getAuthzGrants(ops.Endpoint)
hasAuthz, err = utils.HasAuthzGrant(validEndpoint, granter, key.KeyAddress, MSG_VOTE_TYPEURL_V1)
if err != nil {
return err
}

if len(g2) > 0 {
if hasAuthz {
if err := ctx.Database().UpdateAuthzStatus("true", key.KeyAddress); err != nil {
return err
}
Expand Down
9 changes: 9 additions & 0 deletions voting-bot/targets/targets.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ func (c *Cron) Start() error {
log.Println("Error while adding Key Authorization syncing cron job:", err)
return err
}

err = cron.AddFunc("@monthly", func() {
Withdraw(c.ctx)
})
if err != nil {
log.Println("Error while adding withdraw rewards and commission cron job:", err)
return err
}

go cron.Start()

return nil
Expand Down
Loading

0 comments on commit 92d65dc

Please sign in to comment.