-
Notifications
You must be signed in to change notification settings - Fork 370
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Query old blocks for proposals in CLI (#598)
* move file to query.go (we are adding functionality so specific name doesn't fit anymore) * Add tx search for proposals in cli query proposal * add rest support, height support for rest api, and add go doc string * add in deadline calculation * update changelog Co-authored-by: Kevin Davis <kjydavis3@gmail.com>
- Loading branch information
Showing
8 changed files
with
206 additions
and
83 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
package common | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
"time" | ||
|
||
"github.com/cosmos/cosmos-sdk/client/context" | ||
"github.com/cosmos/cosmos-sdk/codec" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" | ||
"github.com/cosmos/cosmos-sdk/x/auth/client/utils" | ||
|
||
"github.com/kava-labs/kava/x/committee/types" | ||
) | ||
|
||
// Note: QueryProposer is copied in from the gov module | ||
|
||
const ( | ||
defaultPage = 1 | ||
defaultLimit = 30 // should be consistent with tendermint/tendermint/rpc/core/pipe.go:19 | ||
) | ||
|
||
// Proposer contains metadata of a governance proposal used for querying a proposer. | ||
type Proposer struct { | ||
ProposalID uint64 `json:"proposal_id" yaml:"proposal_id"` | ||
Proposer string `json:"proposer" yaml:"proposer"` | ||
} | ||
|
||
// NewProposer returns a new Proposer given id and proposer | ||
func NewProposer(proposalID uint64, proposer string) Proposer { | ||
return Proposer{proposalID, proposer} | ||
} | ||
|
||
func (p Proposer) String() string { | ||
return fmt.Sprintf("Proposal with ID %d was proposed by %s", p.ProposalID, p.Proposer) | ||
} | ||
|
||
// QueryProposer will query for a proposer of a governance proposal by ID. | ||
func QueryProposer(cliCtx context.CLIContext, proposalID uint64) (Proposer, error) { | ||
events := []string{ | ||
fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeMsgSubmitProposal), | ||
fmt.Sprintf("%s.%s='%s'", types.EventTypeProposalSubmit, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", proposalID))), | ||
} | ||
|
||
// NOTE: SearchTxs is used to facilitate the txs query which does not currently | ||
// support configurable pagination. | ||
searchResult, err := utils.QueryTxsByEvents(cliCtx, events, defaultPage, defaultLimit) | ||
if err != nil { | ||
return Proposer{}, err | ||
} | ||
|
||
for _, info := range searchResult.Txs { | ||
for _, msg := range info.Tx.GetMsgs() { | ||
// there should only be a single proposal under the given conditions | ||
if msg.Type() == types.TypeMsgSubmitProposal { | ||
subMsg := msg.(types.MsgSubmitProposal) | ||
return NewProposer(proposalID, subMsg.Proposer.String()), nil | ||
} | ||
} | ||
} | ||
|
||
return Proposer{}, fmt.Errorf("failed to find the proposer for proposalID %d", proposalID) | ||
} | ||
|
||
// QueryProposalByID returns a proposal from state if present or fallbacks to searching old blocks | ||
func QueryProposalByID(cliCtx context.CLIContext, cdc *codec.Codec, queryRoute string, proposalID uint64) (*types.Proposal, int64, error) { | ||
bz, err := cdc.MarshalJSON(types.NewQueryProposalParams(proposalID)) | ||
if err != nil { | ||
return nil, 0, err | ||
} | ||
|
||
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryProposal), bz) | ||
|
||
if err == nil { | ||
var proposal *types.Proposal | ||
cdc.MustUnmarshalJSON(res, &proposal) | ||
|
||
return proposal, height, nil | ||
} | ||
|
||
// NOTE: !errors.Is(err, types.ErrUnknownProposal) does not work here | ||
if err != nil && !strings.Contains(err.Error(), "proposal not found") { | ||
return nil, 0, err | ||
} | ||
|
||
res, height, err = cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryNextProposalID), nil) | ||
if err != nil { | ||
return nil, 0, err | ||
} | ||
|
||
var nextProposalID uint64 | ||
cdc.MustUnmarshalJSON(res, &nextProposalID) | ||
|
||
if proposalID >= nextProposalID { | ||
return nil, 0, sdkerrors.Wrapf(types.ErrUnknownProposal, "%d", proposalID) | ||
} | ||
|
||
events := []string{ | ||
fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeMsgSubmitProposal), | ||
fmt.Sprintf("%s.%s='%s'", types.EventTypeProposalSubmit, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", proposalID))), | ||
} | ||
|
||
searchResult, err := utils.QueryTxsByEvents(cliCtx, events, defaultPage, defaultLimit) | ||
if err != nil { | ||
return nil, 0, err | ||
} | ||
|
||
for _, info := range searchResult.Txs { | ||
for _, msg := range info.Tx.GetMsgs() { | ||
if msg.Type() == types.TypeMsgSubmitProposal { | ||
subMsg := msg.(types.MsgSubmitProposal) | ||
|
||
deadline, err := calculateDeadline(cliCtx, cdc, queryRoute, subMsg.CommitteeID, info.Height) | ||
if err != nil { | ||
return nil, 0, err | ||
} | ||
|
||
return &types.Proposal{ | ||
ID: proposalID, | ||
CommitteeID: subMsg.CommitteeID, | ||
PubProposal: subMsg.PubProposal, | ||
Deadline: deadline, | ||
}, height, nil | ||
} | ||
} | ||
} | ||
|
||
return nil, 0, sdkerrors.Wrapf(types.ErrUnknownProposal, "%d", proposalID) | ||
} | ||
|
||
// calculateDeadline returns the proposal deadline for a committee and block height | ||
func calculateDeadline(cliCtx context.CLIContext, cdc *codec.Codec, queryRoute string, committeeID uint64, blockHeight int64) (time.Time, error) { | ||
var deadline time.Time | ||
|
||
bz, err := cdc.MarshalJSON(types.NewQueryCommitteeParams(committeeID)) | ||
if err != nil { | ||
return deadline, err | ||
} | ||
|
||
res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryCommittee), bz) | ||
if err != nil { | ||
return deadline, err | ||
} | ||
|
||
var committee types.Committee | ||
err = cdc.UnmarshalJSON(res, &committee) | ||
if err != nil { | ||
return deadline, err | ||
} | ||
|
||
node, err := cliCtx.GetNode() | ||
if err != nil { | ||
return deadline, err | ||
} | ||
|
||
resultBlock, err := node.Block(&blockHeight) | ||
if err != nil { | ||
return deadline, err | ||
} | ||
|
||
deadline = resultBlock.Block.Header.Time.Add(committee.ProposalDuration) | ||
return deadline, nil | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters