Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add legacy gov support #105

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading