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

Osmosis Epoch and Protorev Querying #12

Merged
merged 1 commit into from
Jun 13, 2023
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
1,032 changes: 1,032 additions & 0 deletions client/codec/osmosis/v15/x/epochs/types/query.pb.go

Large diffs are not rendered by default.

543 changes: 543 additions & 0 deletions client/codec/osmosis/v15/x/protorev/types/query.pb.go

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
gammTypes "github.com/DefiantLabs/probe/client/codec/osmosis/v15/x/gamm/types"
poolmanagerTypes "github.com/DefiantLabs/probe/client/codec/osmosis/v15/x/poolmanager/types"
querier "github.com/DefiantLabs/probe/query"
osmosisQueryTypes "github.com/DefiantLabs/probe/query/osmosis"
cosmosTypes "github.com/cosmos/cosmos-sdk/types"
cquery "github.com/cosmos/cosmos-sdk/types/query"
ibcChanTypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"
Expand Down Expand Up @@ -110,6 +111,40 @@ func main() {
}
}
}

// Osmosis specific querying proof of concepts

// Get the latest Epoch data

if cconfig.ChainID == "osmosis-1" {
epochData, err := osmosisQueryTypes.EpochsAtHeightRPC(&query, checkHeight)

if err != nil {
fmt.Println("Error getting epoch results")
fmt.Println(err)
os.Exit(1)
}

fmt.Println("Got epoch results, some data follows:")
for _, epoch := range epochData.Epochs {
fmt.Printf("Epoch Identifier: %+v\n", epoch.Identifier)
fmt.Printf("Epoch Current Start Height: %+v\n", epoch.CurrentEpochStartHeight)
fmt.Printf("Epoch Duration: %+v\n", epoch.Duration)
}

protorevDevAccountData, err := osmosisQueryTypes.ProtorevDeveloperAccountRPC(&query)

if err != nil {
fmt.Println("Error getting protorev results")
fmt.Println(err)
os.Exit(1)
}

fmt.Println("Got protorev results, some data follows:")
fmt.Println("Protorev Developer Account Address: ", protorevDevAccountData.DeveloperAccount)

}

}

var handlers = map[string]func(cosmosTypes.Msg){
Expand Down
78 changes: 78 additions & 0 deletions proto/osmosis/epochs/v1beta1/query.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
syntax = "proto3";
package osmosis.epochs.v1beta1;

import "gogoproto/gogo.proto";
import "cosmos/base/query/v1beta1/pagination.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";

option go_package = "github.com/DefiantLabs/probe/client/codec/osmosis/v15/x/epochs/types";

// Query defines the gRPC querier service.
service Query {
// EpochInfos provide running epochInfos
rpc EpochInfos(QueryEpochsInfoRequest) returns (QueryEpochsInfoResponse) {
}
}

message QueryEpochsInfoRequest {}
message QueryEpochsInfoResponse {
repeated EpochInfo epochs = 1 [ (gogoproto.nullable) = false ];
}

message EpochInfo {
// identifier is a unique reference to this particular timer.
string identifier = 1;
// start_time is the time at which the timer first ever ticks.
// If start_time is in the future, the epoch will not begin until the start
// time.
google.protobuf.Timestamp start_time = 2 [
(gogoproto.stdtime) = true,
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"start_time\""
];
// duration is the time in between epoch ticks.
// In order for intended behavior to be met, duration should
// be greater than the chains expected block time.
// Duration must be non-zero.
google.protobuf.Duration duration = 3 [
(gogoproto.nullable) = false,
(gogoproto.stdduration) = true,
(gogoproto.jsontag) = "duration,omitempty",
(gogoproto.moretags) = "yaml:\"duration\""
];
// current_epoch is the current epoch number, or in other words,
// how many times has the timer 'ticked'.
// The first tick (current_epoch=1) is defined as
// the first block whose blocktime is greater than the EpochInfo start_time.
int64 current_epoch = 4;
// current_epoch_start_time describes the start time of the current timer
// interval. The interval is (current_epoch_start_time,
// current_epoch_start_time + duration] When the timer ticks, this is set to
// current_epoch_start_time = last_epoch_start_time + duration only one timer
// tick for a given identifier can occur per block.
//
// NOTE! The current_epoch_start_time may diverge significantly from the
// wall-clock time the epoch began at. Wall-clock time of epoch start may be
// >> current_epoch_start_time. Suppose current_epoch_start_time = 10,
// duration = 5. Suppose the chain goes offline at t=14, and comes back online
// at t=30, and produces blocks at every successive time. (t=31, 32, etc.)
// * The t=30 block will start the epoch for (10, 15]
// * The t=31 block will start the epoch for (15, 20]
// * The t=32 block will start the epoch for (20, 25]
// * The t=33 block will start the epoch for (25, 30]
// * The t=34 block will start the epoch for (30, 35]
// * The **t=36** block will start the epoch for (35, 40]
google.protobuf.Timestamp current_epoch_start_time = 5 [
(gogoproto.stdtime) = true,
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"current_epoch_start_time\""
];
// epoch_counting_started is a boolean, that indicates whether this
// epoch timer has began yet.
bool epoch_counting_started = 6;
reserved 7;
// current_epoch_start_height is the block height at which the current epoch
// started. (The block height at which the timer last ticked)
int64 current_epoch_start_height = 8;
}
29 changes: 29 additions & 0 deletions proto/osmosis/protorev/v1beta1/query.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
syntax = "proto3";
package osmosis.protorev.v1beta1;

import "gogoproto/gogo.proto";
import "cosmos/base/query/v1beta1/pagination.proto";

option go_package = "github.com/DefiantLabs/probe/client/codec/osmosis/v15/x/protorev/types";

// Query defines the gRPC querier service.
service Query {

// GetProtoRevDeveloperAccount queries the developer account of the module
rpc GetProtoRevDeveloperAccount(QueryGetProtoRevDeveloperAccountRequest)
returns (QueryGetProtoRevDeveloperAccountResponse) {
}

}

// QueryGetProtoRevDeveloperAccountRequest is request type for the
// Query/GetProtoRevDeveloperAccount RPC method.
message QueryGetProtoRevDeveloperAccountRequest {}

// QueryGetProtoRevDeveloperAccountResponse is response type for the
// Query/GetProtoRevDeveloperAccount RPC method.
message QueryGetProtoRevDeveloperAccountResponse {
// developer_account is the developer account of the module
string developer_account = 1
[ (gogoproto.moretags) = "yaml:\"developer_account\"" ];
}
40 changes: 40 additions & 0 deletions query/osmosis/epochs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package query

import (
"fmt"

epochsTypes "github.com/DefiantLabs/probe/client/codec/osmosis/v15/x/epochs/types"
queryTypes "github.com/DefiantLabs/probe/query"
coretypes "github.com/cometbft/cometbft/rpc/core/types"
)

func EpochsAtHeightRPC(q *queryTypes.Query, height int64) (*epochsTypes.QueryEpochsInfoResponse, error) {
req := epochsTypes.QueryEpochsInfoRequest{}
queryClient := epochsTypes.NewQueryClient(q.Client)

if height > 0 {
q.Options.Height = height
}

ctx, cancel := q.GetQueryContext()
defer cancel()
res, err := queryClient.EpochInfos(ctx, &req)
if err != nil {
return nil, err
}
return res, nil
}

// BlockSearchEpochStartsLessThanHeightRPC searches for blocks with the epoch_start.epoch_number event with height less than the given height. This query only makes sense for Osmosis, which has the Epoch module emitting this event
// in the BeginBlock events.
func BlockSearchEpochStartsLessThanHeightRPC(q *queryTypes.Query, height int64, page int, perPage int) (*coretypes.ResultBlockSearch, error) {
ctx, cancel := q.GetQueryContext()
defer cancel()

resp, err := q.Client.RPCClient.BlockSearch(ctx, fmt.Sprintf("block.height<%d AND epoch_start.epoch_number EXISTS", height), &page, &perPage, "")
if err != nil {
return nil, err
}

return resp, nil
}
18 changes: 18 additions & 0 deletions query/osmosis/protorev.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package query

import (
protorevTypes "github.com/DefiantLabs/probe/client/codec/osmosis/v15/x/protorev/types"
queryTypes "github.com/DefiantLabs/probe/query"
)

func ProtorevDeveloperAccountRPC(q *queryTypes.Query) (*protorevTypes.QueryGetProtoRevDeveloperAccountResponse, error) {
req := protorevTypes.QueryGetProtoRevDeveloperAccountRequest{}
queryClient := protorevTypes.NewQueryClient(q.Client)
ctx, cancel := q.GetQueryContext()
defer cancel()
res, err := queryClient.GetProtoRevDeveloperAccount(ctx, &req)
if err != nil {
return nil, err
}
return res, nil
}
50 changes: 50 additions & 0 deletions third_party/proto/cosmos/base/query/v1beta1/pagination.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
syntax = "proto3";
package cosmos.base.query.v1beta1;

option go_package = "github.com/cosmos/cosmos-sdk/types/query";

// PageRequest is to be embedded in gRPC request messages for efficient
// pagination. Ex:
//
// message SomeRequest {
// Foo some_parameter = 1;
// PageRequest pagination = 2;
// }
message PageRequest {
// key is a value returned in PageResponse.next_key to begin
// querying the next page most efficiently. Only one of offset or key
// should be set.
bytes key = 1;

// offset is a numeric offset that can be used when key is unavailable.
// It is less efficient than using key. Only one of offset or key should
// be set.
uint64 offset = 2;

// limit is the total number of results to be returned in the result page.
// If left empty it will default to a value to be set by each app.
uint64 limit = 3;

// count_total is set to true to indicate that the result set should include
// a count of the total number of items available for pagination in UIs.
// count_total is only respected when offset is used. It is ignored when key
// is set.
bool count_total = 4;
}

// PageResponse is to be embedded in gRPC response messages where the
// corresponding request message has used PageRequest.
//
// message SomeResponse {
// repeated Bar results = 1;
// PageResponse page = 2;
// }
message PageResponse {
// next_key is the key to be passed to PageRequest.key to
// query the next page most efficiently
bytes next_key = 1;

// total is total number of results available if PageRequest.count_total
// was set, its value is undefined otherwise
uint64 total = 2;
}