Skip to content

Commit

Permalink
feat: store and verify votes fetch height (#73)
Browse files Browse the repository at this point in the history
  • Loading branch information
freak12techno committed Apr 25, 2024
1 parent 401e40f commit 434ae2c
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 20 deletions.
27 changes: 20 additions & 7 deletions pkg/fetchers/cosmos/vote.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,56 @@ import (
"fmt"
"main/pkg/fetchers/cosmos/responses"
"main/pkg/types"
"main/pkg/utils"
"strings"
)

func (rpc *RPC) GetVote(proposal, voter string) (*types.Vote, *types.QueryError) {
func (rpc *RPC) GetVote(proposal, voter string, prevHeight int64) (*types.Vote, int64, *types.QueryError) {
url := fmt.Sprintf(
"/cosmos/gov/v1beta1/proposals/%s/votes/%s",
proposal,
voter,
)

var vote responses.VoteRPCResponse
if errs := rpc.Client.Get(url, &vote); len(errs) > 0 {
return nil, &types.QueryError{
errs, header := rpc.Client.GetWithPredicate(
url,
&vote,
types.HTTPPredicateCheckHeightAfter(prevHeight),
)
if len(errs) > 0 {
return nil, 0, &types.QueryError{
QueryError: nil,
NodeErrors: errs,
}
}

height, err := utils.GetBlockHeightFromHeader(header)
if err != nil {
return nil, 0, &types.QueryError{
QueryError: errors.New("got error when parsing vote height"),
}
}

if vote.IsError() {
// not voted
if strings.Contains(vote.Message, "not found") {
return nil, nil
return nil, height, nil
}

// some other errors
return nil, &types.QueryError{
return nil, height, &types.QueryError{
QueryError: errors.New(vote.Message),
}
}

voteParsed, err := vote.ToVote()
if err != nil {
return nil, &types.QueryError{
return nil, height, &types.QueryError{
QueryError: err,
NodeErrors: nil,
}
}

return voteParsed, nil
return voteParsed, height, nil
}
2 changes: 1 addition & 1 deletion pkg/fetchers/fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (

type Fetcher interface {
GetAllProposals() ([]types.Proposal, *types.QueryError)
GetVote(proposal, voter string) (*types.Vote, *types.QueryError)
GetVote(proposal, voter string, prevHeight int64) (*types.Vote, int64, *types.QueryError)
GetTallies() (types.ChainTallyInfos, error)

GetChainParams() (*types.ChainWithVotingParams, []error)
Expand Down
26 changes: 22 additions & 4 deletions pkg/fetchers/neutron/fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package neutron

import (
"encoding/base64"
"errors"
"fmt"
"main/pkg/http"
"main/pkg/types"
"main/pkg/utils"

"github.com/rs/zerolog"
)
Expand All @@ -23,7 +25,11 @@ func NewFetcher(chainConfig *types.Chain, logger zerolog.Logger) *Fetcher {
}
}

func (fetcher *Fetcher) GetSmartContractState(queryString string, output interface{}) *types.QueryError {
func (fetcher *Fetcher) GetSmartContractState(
queryString string,
output interface{},
prevHeight int64,
) (int64, *types.QueryError) {
query := base64.StdEncoding.EncodeToString([]byte(queryString))

url := fmt.Sprintf(
Expand All @@ -32,12 +38,24 @@ func (fetcher *Fetcher) GetSmartContractState(queryString string, output interfa
query,
)

if errs := fetcher.Client.Get(url, &output); len(errs) > 0 {
return &types.QueryError{
errs, header := fetcher.Client.GetWithPredicate(
url,
&output,
types.HTTPPredicateCheckHeightAfter(prevHeight),
)
if len(errs) > 0 {
return 0, &types.QueryError{
QueryError: nil,
NodeErrors: errs,
}
}

return nil
height, err := utils.GetBlockHeightFromHeader(header)
if err != nil {
return 0, &types.QueryError{
QueryError: errors.New("got error when parsing vote height"),
}
}

return height, nil
}
2 changes: 1 addition & 1 deletion pkg/fetchers/neutron/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ func (fetcher *Fetcher) GetChainParams() (*types.ChainWithVotingParams, []error)
query := "{\"config\":{}}"

var params responses.ParamsResponse
if err := fetcher.GetSmartContractState(query, &params); err != nil {
if _, err := fetcher.GetSmartContractState(query, &params, 0); err != nil {
return nil, []error{err}
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/fetchers/neutron/proposals.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ func (fetcher *Fetcher) GetAllProposals() ([]types.Proposal, *types.QueryError)
query := "{\"list_proposals\": {}}"

var proposals responses.ProposalsResponse
if err := fetcher.GetSmartContractState(query, &proposals); err != nil {
if _, err := fetcher.GetSmartContractState(query, &proposals, 0); err != nil {
return nil, err
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/fetchers/neutron/tally.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ func (fetcher *Fetcher) GetTallies() (types.ChainTallyInfos, error) {
query := "{\"list_proposals\": {}}"

var proposals responses.ProposalsResponse
if err := fetcher.GetSmartContractState(query, &proposals); err != nil {
if _, err := fetcher.GetSmartContractState(query, &proposals, 0); err != nil {
return types.ChainTallyInfos{}, err
}

Expand Down
12 changes: 8 additions & 4 deletions pkg/fetchers/neutron/vote.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,22 @@ import (
"main/pkg/types"
)

func (fetcher *Fetcher) GetVote(proposal, voter string) (*types.Vote, *types.QueryError) {
func (fetcher *Fetcher) GetVote(
proposal, voter string,
prevHeight int64,
) (*types.Vote, int64, *types.QueryError) {
query := fmt.Sprintf(
"{\"get_vote\":{\"proposal_id\":%s,\"voter\":\"%s\"}}",
proposal,
voter,
)

var vote responses.VoteResponse
if err := fetcher.GetSmartContractState(query, &vote); err != nil {
return nil, err
height, err := fetcher.GetSmartContractState(query, &vote, prevHeight)
if err != nil {
return nil, 0, err
}

voteParsed := vote.ToVote(proposal)
return voteParsed, nil
return voteParsed, height, nil
}
3 changes: 2 additions & 1 deletion pkg/state/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func (g *Generator) ProcessProposalAndWallet(
oldState State,
) {
oldVote, _, found := oldState.GetVoteAndProposal(chain.Name, proposal.ID, wallet.Address)
vote, err := fetcher.GetVote(proposal.ID, wallet.Address)
vote, voteHeight, err := fetcher.GetVote(proposal.ID, wallet.Address, oldVote.Height)

if found && oldVote.HasVoted() && vote == nil {
g.Logger.Trace().
Expand All @@ -130,6 +130,7 @@ func (g *Generator) ProcessProposalAndWallet(
proposalVote.Error = err
} else {
proposalVote.Vote = vote
proposalVote.Height = voteHeight
}

g.Mutex.Lock()
Expand Down
1 change: 1 addition & 0 deletions pkg/state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type ProposalVote struct {
Wallet *types.Wallet
Vote *types.Vote
Error *types.QueryError
Height int64
}

func (v ProposalVote) HasVoted() bool {
Expand Down

0 comments on commit 434ae2c

Please sign in to comment.