Skip to content

Commit

Permalink
fix: re-add support for gov v1beta1 msgs
Browse files Browse the repository at this point in the history
  • Loading branch information
dadamu committed Mar 20, 2024
1 parent 6f9af04 commit 890cbb1
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 49 deletions.
20 changes: 17 additions & 3 deletions cmd/parse/gov/proposal.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,11 @@ func refreshProposalDetails(parseCtx *parser.Context, proposalID uint64, govModu

// Handle the MsgSubmitProposal messages
for index, msg := range tx.GetMsgs() {
if _, ok := msg.(*govtypesv1beta1.MsgSubmitProposal); !ok {
_, isMsgSubmitProposalV1 := msg.(*govtypesv1.MsgSubmitProposal)
_, isMsgSubmitProposalV1Beta1 := msg.(*govtypesv1beta1.MsgSubmitProposal)

// Skip if the message is not a submit proposal message
if !isMsgSubmitProposalV1 && !isMsgSubmitProposalV1Beta1 {
continue
}

Expand Down Expand Up @@ -145,7 +149,11 @@ func refreshProposalDeposits(parseCtx *parser.Context, proposalID uint64, govMod

// Handle the MsgDeposit messages
for index, msg := range junoTx.GetMsgs() {
if _, ok := msg.(*govtypesv1.MsgDeposit); !ok {
_, isMsgDepositV1beta1 := msg.(*govtypesv1beta1.MsgDeposit)
_, isMsgDepositV1 := msg.(*govtypesv1.MsgDeposit)

// Skip if the message is not a deposit message
if !isMsgDepositV1 && !isMsgDepositV1beta1 {
continue
}

Expand Down Expand Up @@ -177,7 +185,13 @@ func refreshProposalVotes(parseCtx *parser.Context, proposalID uint64, govModule

// Handle the MsgVote messages
for index, msg := range junoTx.GetMsgs() {
if _, ok := msg.(*govtypesv1.MsgVote); !ok {
_, isMsgVoteV1 := msg.(*govtypesv1.MsgVote)
_, isMsgVoteV1Beta1 := msg.(*govtypesv1beta1.MsgVote)
_, isMsgVoteWeightedV1 := msg.(*govtypesv1.MsgVoteWeighted)
_, isMsgVoteWeightedV1Beta1 := msg.(*govtypesv1beta1.MsgVoteWeighted)

// Skip if the message is not a vote message
if !isMsgVoteV1 && !isMsgVoteV1Beta1 && !isMsgVoteWeightedV1 && !isMsgVoteWeightedV1Beta1 {
continue
}

Expand Down
100 changes: 58 additions & 42 deletions modules/gov/handle_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,14 @@ import (
"fmt"
"time"

"strconv"

"github.com/cosmos/cosmos-sdk/x/authz"

"github.com/forbole/bdjuno/v4/types"

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

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

juno "github.com/forbole/juno/v4/types"
)

Expand All @@ -30,35 +27,36 @@ func (m *Module) HandleMsg(index int, msg sdk.Msg, tx *juno.Tx) error {
}

switch cosmosMsg := msg.(type) {
case *govtypesv1.MsgSubmitProposal:
return m.handleSubmitProposalEvent(tx, cosmosMsg.Proposer, tx.Logs[index].Events)
case *govtypesv1beta1.MsgSubmitProposal:
return m.handleMsgSubmitProposal(tx, index, cosmosMsg)
return m.handleSubmitProposalEvent(tx, cosmosMsg.Proposer, tx.Logs[index].Events)

case *govtypesv1.MsgDeposit:
return m.handleMsgDeposit(tx, cosmosMsg)
return m.handleDepositEvent(tx, cosmosMsg.Depositor, tx.Logs[index].Events)
case *govtypesv1beta1.MsgDeposit:
return m.handleDepositEvent(tx, cosmosMsg.Depositor, tx.Logs[index].Events)

case *govtypesv1.MsgVote:
return m.handleMsgVote(tx, cosmosMsg)
return m.handleVoteEvent(tx, cosmosMsg.Voter, tx.Logs[index].Events)
case *govtypesv1beta1.MsgVote:
return m.handleVoteEvent(tx, cosmosMsg.Voter, tx.Logs[index].Events)

case *govtypesv1.MsgVoteWeighted:
return m.handleVoteEvent(tx, cosmosMsg.Voter, tx.Logs[index].Events)
case *govtypesv1beta1.MsgVoteWeighted:
return m.handleVoteEvent(tx, cosmosMsg.Voter, tx.Logs[index].Events)
}

return nil
}

// handleMsgSubmitProposal allows to properly handle a handleMsgSubmitProposal
func (m *Module) handleMsgSubmitProposal(tx *juno.Tx, index int, msg *govtypesv1beta1.MsgSubmitProposal) error {
// handleSubmitProposalEvent allows to properly handle a handleSubmitProposalEvent
func (m *Module) handleSubmitProposalEvent(tx *juno.Tx, proposer string, events sdk.StringEvents) error {
// Get the proposal id
event, err := tx.FindEventByType(index, gov.EventTypeSubmitProposal)
proposalID, err := ProposalIDFromEvents(events)
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)
return fmt.Errorf("error while getting proposal id: %s", err)
}

// Get the proposal
Expand All @@ -67,38 +65,44 @@ func (m *Module) handleMsgSubmitProposal(tx *juno.Tx, index int, msg *govtypesv1
return fmt.Errorf("error while getting proposal: %s", err)
}

// Unpack the proposal interfaces
err = proposal.UnpackInterfaces(m.cdc)
if err != nil {
return fmt.Errorf("error while unpacking proposal interfaces: %s", err)
}

// Store the proposal
proposalObj := types.NewProposal(
proposal.ProposalId,
msg.GetContent().ProposalRoute(),
msg.GetContent().ProposalType(),
msg.GetContent(),
proposal.GetContent().ProposalRoute(),
proposal.GetContent().ProposalType(),
proposal.GetContent(),
proposal.Status.String(),
proposal.SubmitTime,
proposal.DepositEndTime,
proposal.VotingStartTime,
proposal.VotingEndTime,
msg.Proposer,
proposer,
)

err = m.db.SaveProposals([]types.Proposal{proposalObj})
if err != nil {
return err
return fmt.Errorf("error while saving proposal: %s", err)
}

txTimestamp, err := time.Parse(time.RFC3339, tx.Timestamp)
// Submit proposal must have a deposit event with depositor equal to the proposer
return m.handleDepositEvent(tx, proposer, events)
}

// handleDepositEvent allows to properly handle a handleDepositEvent
func (m *Module) handleDepositEvent(tx *juno.Tx, depositor string, events sdk.StringEvents) error {
// Get the proposal id
proposalID, err := ProposalIDFromEvents(events)
if err != nil {
return fmt.Errorf("error while parsing time: %s", err)
return fmt.Errorf("error while getting proposal id: %s", err)
}

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

// handleMsgDeposit allows to properly handle a handleMsgDeposit
func (m *Module) handleMsgDeposit(tx *juno.Tx, msg *govtypesv1.MsgDeposit) error {
deposit, err := m.source.ProposalDeposit(tx.Height, msg.ProposalId, msg.Depositor)
deposit, err := m.source.ProposalDeposit(tx.Height, proposalID, depositor)
if err != nil {
return fmt.Errorf("error while getting proposal deposit: %s", err)
}
Expand All @@ -108,18 +112,30 @@ func (m *Module) handleMsgDeposit(tx *juno.Tx, msg *govtypesv1.MsgDeposit) error
}

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

// handleMsgVote allows to properly handle a handleMsgVote
func (m *Module) handleMsgVote(tx *juno.Tx, msg *govtypesv1.MsgVote) error {
// handleVoteEvent allows to properly handle a handleVoteEvent
func (m *Module) handleVoteEvent(tx *juno.Tx, voter string, events sdk.StringEvents) error {
// Get the proposal id
proposalID, err := ProposalIDFromEvents(events)
if err != nil {
return fmt.Errorf("error while getting proposal id: %s", err)
}

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

vote := types.NewVote(msg.ProposalId, msg.Voter, msg.Option, txTimestamp, tx.Height)
// Get the vote option
voteOption, err := VoteOptionFromEvents(events)
if err != nil {
return fmt.Errorf("error while getting vote option: %s", err)
}

vote := types.NewVote(proposalID, voter, voteOption, txTimestamp, tx.Height)

return m.db.SaveVote(vote)
}
9 changes: 5 additions & 4 deletions modules/gov/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ import (
)

var (
_ modules.Module = &Module{}
_ modules.GenesisModule = &Module{}
_ modules.BlockModule = &Module{}
_ modules.MessageModule = &Module{}
_ modules.Module = &Module{}
_ modules.GenesisModule = &Module{}
_ modules.BlockModule = &Module{}
_ modules.MessageModule = &Module{}
_ modules.AuthzMessageModule = &Module{}
)

// Module represent x/gov module
Expand Down
63 changes: 63 additions & 0 deletions modules/gov/utils_events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package gov

import (
"encoding/json"
"fmt"
"strconv"
"strings"

sdk "github.com/cosmos/cosmos-sdk/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
eventsutil "github.com/forbole/bdjuno/v4/utils/events"
)

// ProposalIDFromEvent returns the proposal id from the given events
func ProposalIDFromEvents(events sdk.StringEvents) (uint64, error) {
for _, event := range events {
attribute, ok := eventsutil.FindAttributeByKey(event, govtypes.AttributeKeyProposalID)
if ok {
return strconv.ParseUint(attribute.Value, 10, 64)
}
}

return 0, fmt.Errorf("no proposal id found")
}

// VoteOptionFromEvents returns the vote option from the given events
func VoteOptionFromEvents(events sdk.StringEvents) (govtypesv1.VoteOption, error) {
for _, event := range events {
attribute, ok := eventsutil.FindAttributeByKey(event, govtypes.AttributeKeyOption)
if ok {
return parseVoteOption(attribute.Value)
}
}

return 0, fmt.Errorf("no vote option found")
}

// parseVoteOption returns the vote option from the given string
// option value in string could be 2 cases, for example:
// 1. "{\"option\":1,\"weight\":\"1.000000000000000000\"}"
// 2. "option:VOTE_OPTION_NO weight:\"1.000000000000000000\""
func parseVoteOption(optionValue string) (govtypesv1.VoteOption, error) {
// try parse option value as json
type voteOptionJSON struct {
Option govtypesv1.VoteOption `json:"option"`
}
var voteOptionParsedJSON voteOptionJSON
err := json.Unmarshal([]byte(optionValue), &voteOptionParsedJSON)
if err == nil {
return voteOptionParsedJSON.Option, nil
}

// try parse option value as string
// option:VOTE_OPTION_NO weight:"1.000000000000000000"
voteOptionParsed := strings.Split(optionValue, " ")
voteOption, err := govtypesv1.VoteOptionFromString(strings.ReplaceAll(voteOptionParsed[0], "option:", ""))
if err != nil {
return 0, fmt.Errorf("failed to parse vote option %s: %s", optionValue, err)
}

return voteOption, nil
}
25 changes: 25 additions & 0 deletions utils/events/events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package events

import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

// FindEventByType returns the event with the given type
func FindEventByType(events sdk.StringEvents, eventType string) (sdk.StringEvent, bool) {
for _, event := range events {
if event.Type == eventType {
return event, true
}
}
return sdk.StringEvent{}, false
}

// FindAttributeByKey returns the attribute with the given key
func FindAttributeByKey(event sdk.StringEvent, key string) (sdk.Attribute, bool) {
for _, attribute := range event.Attributes {
if attribute.Key == key {
return attribute, true
}
}
return sdk.Attribute{}, false
}

0 comments on commit 890cbb1

Please sign in to comment.