From 7759112dac362433ceaa07abdc0d2afcffa73507 Mon Sep 17 00:00:00 2001 From: olegfomenko Date: Thu, 9 May 2024 15:44:46 +0300 Subject: [PATCH 1/2] adding block events handler to save new proposals --- modules/gov/handle_block.go | 115 +++++++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 3 deletions(-) diff --git a/modules/gov/handle_block.go b/modules/gov/handle_block.go index 6d758e3..cadfabd 100644 --- a/modules/gov/handle_block.go +++ b/modules/gov/handle_block.go @@ -1,19 +1,38 @@ package gov import ( + "encoding/json" "fmt" - + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/types/bech32" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govtypesv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" juno "github.com/forbole/juno/v4/types" - + "github.com/gogo/protobuf/proto" + "github.com/rarimo/bdjuno/types" + "github.com/rarimo/rarimo-core/app" + abci "github.com/tendermint/tendermint/abci/types" tmctypes "github.com/tendermint/tendermint/rpc/core/types" + "strconv" "github.com/rs/zerolog/log" ) // HandleBlock implements modules.BlockModule func (m *Module) HandleBlock( - b *tmctypes.ResultBlock, _ *tmctypes.ResultBlockResults, _ []*juno.Tx, vals *tmctypes.ResultValidators, + b *tmctypes.ResultBlock, res *tmctypes.ResultBlockResults, _ []*juno.Tx, vals *tmctypes.ResultValidators, ) error { + if err := m.handleBlockEvents(b.Block.Height, res.BeginBlockEvents); err != nil { + log.Error().Str("module", "gov").Int64("height", b.Block.Height). + Err(err).Msg("error while processing end block events") + } + + if err := m.handleBlockEvents(b.Block.Height, res.EndBlockEvents); err != nil { + log.Error().Str("module", "gov").Int64("height", b.Block.Height). + Err(err).Msg("error while processing end block events") + } + err := m.updateProposals(b.Block.Height, vals) if err != nil { log.Error().Str("module", "gov").Int64("height", b.Block.Height). @@ -42,3 +61,93 @@ func (m *Module) updateProposals(height int64, blockVals *tmctypes.ResultValidat } return nil } + +func (m *Module) handleBlockEvents(height int64, events []abci.Event) error { + events = juno.FindEventsByType(events, govtypes.EventTypeSubmitProposal) + + for _, event := range events { + proposalIdAttribute, err := juno.FindAttributeByKey(event, govtypes.AttributeKeyProposalID) + if err != nil { + // error means to such attribute - normal logic + continue + } + + proposalId, err := strconv.ParseUint(string(proposalIdAttribute.Value), 10, 64) + if err != nil { + return fmt.Errorf("error while parsing proposal id atribute: %s", err) + } + + // !! Logic partially copied from handleMsgSubmitProposal method + + proposal, err := m.source.Proposal(height, proposalId) + if err != nil { + return fmt.Errorf("error while getting proposal: %s", err) + } + + // Unpack the content + var content govtypesv1beta1.Content + err = m.cdc.UnpackAny(proposal.Content, &content) + if err != nil { + return fmt.Errorf("error while unpacking proposal content: %s", err) + } + + // Encode the content properly + protoContent, ok := content.(proto.Message) + if !ok { + return fmt.Errorf("invalid proposal content types: %T", proposal.Content) + } + + anyContent, err := codectypes.NewAnyWithValue(protoContent) + if err != nil { + return fmt.Errorf("error while wrapping proposal proto content: %s", err) + } + + contentBz, err := m.db.EncodingConfig.Codec.MarshalJSON(anyContent) + if err != nil { + return fmt.Errorf("error while marshaling proposal content: %s", err) + } + + metadata := map[string]string{ + "title": proposal.GetContent().GetTitle(), + "description": proposal.GetContent().GetDescription(), + "type": proposal.ProposalType(), + } + + metadataBz, err := json.Marshal(metadata) + if err != nil { + return fmt.Errorf("error while marshaling proposal metadata: %s", err) + } + + // !! If proposal was created in Block events then the proposer will be defined as module account + govModuleAddress, err := bech32.ConvertAndEncode( + app.AccountAddressPrefix, + authtypes.NewModuleAddress(govtypes.ModuleName).Bytes(), + ) + if err != nil { + panic(fmt.Errorf("failed to convert module address %s", err)) + } + + // Store the proposal + proposalObj := types.NewProposal( + proposal.ProposalId, + string(contentBz), + proposal.Status.String(), + proposal.SubmitBlock, + proposal.DepositEndBlock, + proposal.VotingStartBlock, + proposal.VotingEndBlock, + govModuleAddress, + string(metadataBz), + ) + err = m.db.SaveProposals([]types.Proposal{proposalObj}) + if err != nil { + return err + } + + // Store the deposit + deposit := types.NewDeposit(proposal.ProposalId, govModuleAddress, proposal.TotalDeposit, height) + return m.db.SaveDeposits([]types.Deposit{deposit}) + } + + return nil +} From 8927aa02771be7ecc34145140c045c96df3cca5e Mon Sep 17 00:00:00 2001 From: olegfomenko Date: Thu, 9 May 2024 15:59:43 +0300 Subject: [PATCH 2/2] ref --- modules/gov/handle_block.go | 150 +++++++++++++++++++----------------- 1 file changed, 79 insertions(+), 71 deletions(-) diff --git a/modules/gov/handle_block.go b/modules/gov/handle_block.go index cadfabd..f670afc 100644 --- a/modules/gov/handle_block.go +++ b/modules/gov/handle_block.go @@ -63,91 +63,99 @@ func (m *Module) updateProposals(height int64, blockVals *tmctypes.ResultValidat } func (m *Module) handleBlockEvents(height int64, events []abci.Event) error { - events = juno.FindEventsByType(events, govtypes.EventTypeSubmitProposal) - for _, event := range events { - proposalIdAttribute, err := juno.FindAttributeByKey(event, govtypes.AttributeKeyProposalID) - if err != nil { - // error means to such attribute - normal logic - continue + switch event.Type { + case govtypes.EventTypeSubmitProposal: + if err := m.handleBlockEventSubmitProposal(height, event); err != nil { + return err + } + // Add other events handling if required } + } - proposalId, err := strconv.ParseUint(string(proposalIdAttribute.Value), 10, 64) - if err != nil { - return fmt.Errorf("error while parsing proposal id atribute: %s", err) - } + return nil +} - // !! Logic partially copied from handleMsgSubmitProposal method +func (m *Module) handleBlockEventSubmitProposal(height int64, event abci.Event) error { + proposalIdAttribute, err := juno.FindAttributeByKey(event, govtypes.AttributeKeyProposalID) + if err != nil { + // error means to such attribute - normal logic + return nil + } - proposal, err := m.source.Proposal(height, proposalId) - if err != nil { - return fmt.Errorf("error while getting proposal: %s", err) - } + proposalId, err := strconv.ParseUint(string(proposalIdAttribute.Value), 10, 64) + if err != nil { + return fmt.Errorf("error while parsing proposal id atribute: %s", err) + } - // Unpack the content - var content govtypesv1beta1.Content - err = m.cdc.UnpackAny(proposal.Content, &content) - if err != nil { - return fmt.Errorf("error while unpacking proposal content: %s", err) - } + // !! Logic partially copied from handleMsgSubmitProposal method - // Encode the content properly - protoContent, ok := content.(proto.Message) - if !ok { - return fmt.Errorf("invalid proposal content types: %T", proposal.Content) - } + proposal, err := m.source.Proposal(height, proposalId) + if err != nil { + return fmt.Errorf("error while getting proposal: %s", err) + } - anyContent, err := codectypes.NewAnyWithValue(protoContent) - if err != nil { - return fmt.Errorf("error while wrapping proposal proto content: %s", err) - } + // Unpack the content + var content govtypesv1beta1.Content + err = m.cdc.UnpackAny(proposal.Content, &content) + if err != nil { + return fmt.Errorf("error while unpacking proposal content: %s", err) + } - contentBz, err := m.db.EncodingConfig.Codec.MarshalJSON(anyContent) - if err != nil { - return fmt.Errorf("error while marshaling proposal content: %s", err) - } + // Encode the content properly + protoContent, ok := content.(proto.Message) + if !ok { + return fmt.Errorf("invalid proposal content types: %T", proposal.Content) + } - metadata := map[string]string{ - "title": proposal.GetContent().GetTitle(), - "description": proposal.GetContent().GetDescription(), - "type": proposal.ProposalType(), - } + anyContent, err := codectypes.NewAnyWithValue(protoContent) + if err != nil { + return fmt.Errorf("error while wrapping proposal proto content: %s", err) + } - metadataBz, err := json.Marshal(metadata) - if err != nil { - return fmt.Errorf("error while marshaling proposal metadata: %s", err) - } + contentBz, err := m.db.EncodingConfig.Codec.MarshalJSON(anyContent) + if err != nil { + return fmt.Errorf("error while marshaling proposal content: %s", err) + } - // !! If proposal was created in Block events then the proposer will be defined as module account - govModuleAddress, err := bech32.ConvertAndEncode( - app.AccountAddressPrefix, - authtypes.NewModuleAddress(govtypes.ModuleName).Bytes(), - ) - if err != nil { - panic(fmt.Errorf("failed to convert module address %s", err)) - } + metadata := map[string]string{ + "title": proposal.GetContent().GetTitle(), + "description": proposal.GetContent().GetDescription(), + "type": proposal.ProposalType(), + } - // Store the proposal - proposalObj := types.NewProposal( - proposal.ProposalId, - string(contentBz), - proposal.Status.String(), - proposal.SubmitBlock, - proposal.DepositEndBlock, - proposal.VotingStartBlock, - proposal.VotingEndBlock, - govModuleAddress, - string(metadataBz), - ) - err = m.db.SaveProposals([]types.Proposal{proposalObj}) - if err != nil { - return err - } + metadataBz, err := json.Marshal(metadata) + if err != nil { + return fmt.Errorf("error while marshaling proposal metadata: %s", err) + } - // Store the deposit - deposit := types.NewDeposit(proposal.ProposalId, govModuleAddress, proposal.TotalDeposit, height) - return m.db.SaveDeposits([]types.Deposit{deposit}) + // !! If proposal was created in Block events then the proposer will be defined as module account + govModuleAddress, err := bech32.ConvertAndEncode( + app.AccountAddressPrefix, + authtypes.NewModuleAddress(govtypes.ModuleName).Bytes(), + ) + if err != nil { + panic(fmt.Errorf("failed to convert module address %s", err)) } - return nil + // Store the proposal + proposalObj := types.NewProposal( + proposal.ProposalId, + string(contentBz), + proposal.Status.String(), + proposal.SubmitBlock, + proposal.DepositEndBlock, + proposal.VotingStartBlock, + proposal.VotingEndBlock, + govModuleAddress, + string(metadataBz), + ) + err = m.db.SaveProposals([]types.Proposal{proposalObj}) + if err != nil { + return err + } + + // Store the deposit + deposit := types.NewDeposit(proposal.ProposalId, govModuleAddress, proposal.TotalDeposit, height) + return m.db.SaveDeposits([]types.Deposit{deposit}) }