Skip to content

Commit

Permalink
Merge pull request #105 from CudoVentures/cudos-dev-cosmos-v0.47.3-v1…
Browse files Browse the repository at this point in the history
…beta1-gov-legacy-support

feat: add legacy gov support
  • Loading branch information
kstoykov authored Oct 20, 2023
2 parents 7049fe0 + 4767892 commit e36959a
Show file tree
Hide file tree
Showing 4 changed files with 259 additions and 26 deletions.
40 changes: 22 additions & 18 deletions cmd/parse/gov/proposal.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
modulestypes "github.com/forbole/bdjuno/v4/modules/types"

govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
legacyTypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
parsecmdtypes "github.com/forbole/juno/v5/cmd/parse/types"
"github.com/forbole/juno/v5/parser"
"github.com/forbole/juno/v5/types/config"
Expand Down Expand Up @@ -113,14 +114,15 @@ func refreshProposalDetails(parseCtx *parser.Context, proposalID uint64, govModu

// Handle the MsgSubmitProposal messages
for index, msg := range tx.GetMsgs() {
if _, ok := msg.(*govtypesv1.MsgSubmitProposal); !ok {
switch msg.(type) {
case *govtypesv1.MsgSubmitProposal, *legacyTypes.MsgSubmitProposal:
err = govModule.HandleMsg(index, msg, tx)
if err != nil {
return fmt.Errorf("error while handling MsgSubmitProposal: %s", err)
}
default:
continue
}

err = govModule.HandleMsg(index, msg, tx)
if err != nil {
return fmt.Errorf("error while handling MsgSubmitProposal: %s", err)
}
}

return nil
Expand All @@ -144,14 +146,15 @@ func refreshProposalDeposits(parseCtx *parser.Context, proposalID uint64, govMod

// Handle the MsgDeposit messages
for index, msg := range junoTx.GetMsgs() {
if _, ok := msg.(*govtypesv1.MsgDeposit); !ok {
switch msg.(type) {
case *govtypesv1.MsgDeposit, *legacyTypes.MsgDeposit:
err = govModule.HandleMsg(index, msg, junoTx)
if err != nil {
return fmt.Errorf("error while handling MsgDeposit: %s", err)
}
default:
continue
}

err = govModule.HandleMsg(index, msg, junoTx)
if err != nil {
return fmt.Errorf("error while handling MsgDeposit: %s", err)
}
}
}

Expand All @@ -176,14 +179,15 @@ func refreshProposalVotes(parseCtx *parser.Context, proposalID uint64, govModule

// Handle the MsgVote messages
for index, msg := range junoTx.GetMsgs() {
if _, ok := msg.(*govtypesv1.MsgVote); !ok {
switch msg.(type) {
case *govtypesv1.MsgVote, *legacyTypes.MsgVote:
err = govModule.HandleMsg(index, msg, junoTx)
if err != nil {
return fmt.Errorf("error while handling MsgVote: %s", err)
}
default:
continue
}

err = govModule.HandleMsg(index, msg, junoTx)
if err != nil {
return fmt.Errorf("error while handling MsgVote: %s", err)
}
}
}

Expand Down
24 changes: 24 additions & 0 deletions database/gov.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,30 @@ WHERE proposal_vote.height <= excluded.height`
return nil
}

func (db *Db) SaveLegacyVote(vote types.LegacyVote) error {
query := `
INSERT INTO proposal_vote (proposal_id, voter_address, option, timestamp, height)
VALUES ($1, $2, $3, $4, $5)
ON CONFLICT ON CONSTRAINT unique_vote DO UPDATE
SET option = excluded.option,
timestamp = excluded.timestamp,
height = excluded.height
WHERE proposal_vote.height <= excluded.height`

// Store the voter account
err := db.SaveAccounts([]types.Account{types.NewAccount(vote.Voter)})
if err != nil {
return fmt.Errorf("error while storing voter account: %s", err)
}

_, err = db.SQL.Exec(query, vote.ProposalID, vote.Voter, vote.Option.String(), vote.Timestamp, vote.Height)
if err != nil {
return fmt.Errorf("error while storing vote: %s", err)
}

return nil
}

func (db *Db) SaveWeightedVote(weightedVote types.WeightedVote) error {
query := `
INSERT INTO proposal_vote_weighted (proposal_id, voter_address, option, weight, height)
Expand Down
176 changes: 168 additions & 8 deletions modules/gov/handle_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

sdk "github.com/cosmos/cosmos-sdk/types"
govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
legacyTypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"

gov "github.com/cosmos/cosmos-sdk/x/gov/types"
juno "github.com/forbole/juno/v5/types"
Expand All @@ -21,23 +22,25 @@ func (m *Module) HandleMsg(index int, msg sdk.Msg, tx *juno.Tx) error {
}

switch cosmosMsg := msg.(type) {
case *govtypesv1.MsgSubmitProposal:
return m.handleMsgSubmitProposal(tx, index, cosmosMsg)
case *govtypesv1.MsgSubmitProposal, *legacyTypes.MsgSubmitProposal:
return m.handleMsgSubmitProposalWithLegacySupport(tx, index, cosmosMsg)

case *govtypesv1.MsgDeposit:
return m.handleMsgDeposit(tx, cosmosMsg)
case *govtypesv1.MsgDeposit, *legacyTypes.MsgDeposit:
return m.handleMsgDepositWithLegacySupport(tx, cosmosMsg)

case *govtypesv1.MsgVote:
return m.handleMsgVote(tx, cosmosMsg)
case *govtypesv1.MsgVote, *legacyTypes.MsgVote:
return m.handleMsgVoteWithLegacySupport(tx, cosmosMsg)

case *govtypesv1.MsgVoteWeighted:
return m.handleMsgVoteWeighted(tx, cosmosMsg)
case *govtypesv1.MsgVoteWeighted, *legacyTypes.MsgVoteWeighted:
return m.handleMsgVoteWeightedWithLegacySupport(tx, cosmosMsg)
}

return nil
}

// handleMsgSubmitProposal allows to properly handle a handleMsgSubmitProposal
//
//lint:ignore U1000 we might need the original implementation later
func (m *Module) handleMsgSubmitProposal(tx *juno.Tx, index int, msg *govtypesv1.MsgSubmitProposal) error {
// Get the proposal id
event, err := tx.FindEventByType(index, gov.EventTypeSubmitProposal)
Expand Down Expand Up @@ -92,6 +95,8 @@ func (m *Module) handleMsgSubmitProposal(tx *juno.Tx, index int, msg *govtypesv1
}

// handleMsgDeposit allows to properly handle a handleMsgDeposit
//
//lint:ignore U1000 we might need the original implementation later
func (m *Module) handleMsgDeposit(tx *juno.Tx, msg *govtypesv1.MsgDeposit) error {
deposit, err := m.source.ProposalDeposit(tx.Height, msg.ProposalId, msg.Depositor)
if err != nil {
Expand All @@ -108,6 +113,8 @@ func (m *Module) handleMsgDeposit(tx *juno.Tx, msg *govtypesv1.MsgDeposit) error
}

// handleMsgVote allows to properly handle a handleMsgVote
//
//lint:ignore U1000 we might need the original implementation later
func (m *Module) handleMsgVote(tx *juno.Tx, msg *govtypesv1.MsgVote) error {
txTimestamp, err := time.Parse(time.RFC3339, tx.Timestamp)
if err != nil {
Expand All @@ -119,7 +126,160 @@ func (m *Module) handleMsgVote(tx *juno.Tx, msg *govtypesv1.MsgVote) error {
return m.db.SaveVote(vote)
}

//lint:ignore U1000 we might need the original implementation later
func (m *Module) handleMsgVoteWeighted(tx *juno.Tx, msg *govtypesv1.MsgVoteWeighted) error {
weightedVote := types.NewWeightedVote(msg.ProposalId, msg.Voter, msg.Options, tx.Height)
return m.db.SaveWeightedVote(weightedVote)
}

// handleMsgSubmitProposal allows to properly handle a handleMsgSubmitProposal
func (m *Module) handleMsgSubmitProposalWithLegacySupport(tx *juno.Tx, index int, msg interface{}) error {
// Get the proposal id
event, err := tx.FindEventByType(index, gov.EventTypeSubmitProposal)
if err != nil {
return fmt.Errorf("error while searching for EventTypeSubmitProposal: %s", err)
}

id, err := tx.FindAttributeByKey(event, gov.AttributeKeyProposalID)
if err != nil {
return fmt.Errorf("error while searching for AttributeKeyProposalID: %s", err)
}

proposalID, err := strconv.ParseUint(id, 10, 64)
if err != nil {
return fmt.Errorf("error while parsing proposal id: %s", err)
}

// Get the proposal
proposal, err := m.source.Proposal(tx.Height, proposalID)
if err != nil {
return fmt.Errorf("error while getting proposal: %s", err)
}

// Prepare the proposalObj
var proposalObj types.Proposal
switch msg.(type) {
case *govtypesv1.MsgSubmitProposal, *legacyTypes.MsgSubmitProposal:
proposalObj = types.NewProposal(
proposal.Id,
proposal.Title,
proposal.Summary,
proposal.Metadata,
proposal.Messages,
proposal.Status.String(),
*proposal.SubmitTime,
*proposal.DepositEndTime,
proposal.VotingStartTime,
proposal.VotingEndTime,
proposal.Proposer,
)
default:
return fmt.Errorf("unexpected type %T", msg)
}

// Get the initialDeposit
var initialDeposit []sdk.Coin
switch msgType := msg.(type) {
case *govtypesv1.MsgSubmitProposal:
initialDeposit = msgType.InitialDeposit
case *legacyTypes.MsgSubmitProposal:
initialDeposit = msgType.InitialDeposit
}

err = m.db.SaveProposals([]types.Proposal{proposalObj})
if err != nil {
return err
}

txTimestamp, err := time.Parse(time.RFC3339, tx.Timestamp)
if err != nil {
return fmt.Errorf("error while parsing time: %s", err)
}

// Store the deposit
deposit := types.NewDeposit(proposal.Id, proposal.Proposer, initialDeposit, txTimestamp, tx.Height)
return m.db.SaveDeposits([]types.Deposit{deposit})
}

func (m *Module) handleMsgDepositWithLegacySupport(tx *juno.Tx, msg interface{}) error {

var proposalID uint64
var depositor string
switch msgType := msg.(type) {
case *govtypesv1.MsgDeposit:
proposalID = msgType.ProposalId
depositor = msgType.Depositor
case *legacyTypes.MsgDeposit:
proposalID = msgType.ProposalId
depositor = msgType.Depositor
}

deposit, err := m.source.ProposalDeposit(tx.Height, proposalID, depositor)
if err != nil {
return fmt.Errorf("error while getting proposal deposit: %s", err)
}
txTimestamp, err := time.Parse(time.RFC3339, tx.Timestamp)
if err != nil {
return fmt.Errorf("error while parsing time: %s", err)
}

return m.db.SaveDeposits([]types.Deposit{
types.NewDeposit(proposalID, depositor, deposit.Amount, txTimestamp, tx.Height),
})
}

func (m *Module) handleMsgVoteWithLegacySupport(tx *juno.Tx, msg interface{}) error {
txTimestamp, err := time.Parse(time.RFC3339, tx.Timestamp)
if err != nil {
return fmt.Errorf("error while parsing time: %s", err)
}

switch msgType := msg.(type) {
case *govtypesv1.MsgVote:
return m.db.SaveVote(
types.NewVote(
msgType.ProposalId,
msgType.Voter,
msgType.Option,
txTimestamp,
tx.Height,
),
)
case *legacyTypes.MsgVote:
return m.db.SaveLegacyVote(
types.NewLegacyVote(
msgType.ProposalId,
msgType.Voter,
msgType.Option,
txTimestamp,
tx.Height,
),
)
}

return fmt.Errorf("error while saving vote")
}

func (m *Module) handleMsgVoteWeightedWithLegacySupport(tx *juno.Tx, msg interface{}) error {
var weightedVote types.WeightedVote
switch msgType := msg.(type) {
case *govtypesv1.MsgVoteWeighted:
weightedVote = types.NewWeightedVote(
msgType.ProposalId,
msgType.Voter,
msgType.Options,
tx.Height,
)
case *legacyTypes.MsgVoteWeighted:
weightedVote = types.NewLegacyWeightedVote(
msgType.ProposalId,
msgType.Voter,
msgType.Options,
tx.Height,
)
default:
return fmt.Errorf("error while saving weighted vote")
}

return m.db.SaveWeightedVote(weightedVote)
}
45 changes: 45 additions & 0 deletions types/gov.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"

govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
legacyTypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
)

const (
Expand Down Expand Up @@ -129,6 +130,14 @@ type Vote struct {
Height int64
}

type LegacyVote struct {
ProposalID uint64
Voter string
Option legacyTypes.VoteOption
Timestamp time.Time
Height int64
}

// NewVote return a new Vote instance
func NewVote(
proposalID uint64,
Expand All @@ -146,6 +155,22 @@ func NewVote(
}
}

func NewLegacyVote(
proposalID uint64,
voter string,
option legacyTypes.VoteOption,
timestamp time.Time,
height int64,
) LegacyVote {
return LegacyVote{
ProposalID: proposalID,
Voter: voter,
Option: option,
Timestamp: timestamp,
Height: height,
}
}

type WeightedVoteOption struct {
Option string
Weight string
Expand Down Expand Up @@ -178,6 +203,26 @@ func NewWeightedVote(
return weightedvote
}

func NewLegacyWeightedVote(
proposalID uint64,
voter string,
options []legacyTypes.WeightedVoteOption,
height int64,
) WeightedVote {
weightedvote := WeightedVote{
ProposalID: proposalID,
Voter: voter,
Height: height,
}
for _, opt := range options {
weightedvote.Options = append(weightedvote.Options, WeightedVoteOption{
Option: govtypesv1.VoteOption_name[int32(opt.Option)],
Weight: opt.Weight.String(),
})
}
return weightedvote
}

// -------------------------------------------------------------------------------------------------------------------

// TallyResult contains the data about the final results of a proposal
Expand Down

0 comments on commit e36959a

Please sign in to comment.