Skip to content

Commit 7f00c50

Browse files
committed
feat(delegators): add --min-shares / --max-shares filters
1 parent e919fdd commit 7f00c50

File tree

5 files changed

+120
-24
lines changed

5 files changed

+120
-24
lines changed

cmd/delegators.go

+52-8
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,27 @@ import (
44
"github.com/axone-protocol/cosmos-extractor/pkg/delegators"
55
"github.com/spf13/cobra"
66
"github.com/teambenny/goetl"
7+
8+
"cosmossdk.io/math"
79
)
810

911
const (
10-
flagHrp = "hrp"
12+
flagHrp = "hrp"
13+
flagMinShares = "min-shares"
14+
flagMaxShares = "max-shares"
1115
)
1216

1317
var extractDelegatorsCmd = &cobra.Command{
1418
Use: "delegators [source]",
1519
Short: "Extract all delegators",
1620
Args: cobra.ExactArgs(1),
1721
RunE: func(cmd *cobra.Command, args []string) error {
18-
chainName, _ := cmd.Flags().GetString(flagChainName)
19-
src := args[0]
20-
21-
processors := []goetl.Processor{}
22-
23-
read, err := delegators.NewDelegatorsReader(chainName, src, logger)
22+
read, err := newDelegatorsReader(cmd, args)
2423
if err != nil {
2524
return err
2625
}
26+
27+
processors := []goetl.Processor{}
2728
processors = append(processors, read)
2829

2930
hrps, err := cmd.Flags().GetStringSlice(flagHrp)
@@ -52,13 +53,56 @@ var extractDelegatorsCmd = &cobra.Command{
5253
},
5354
}
5455

56+
func newDelegatorsReader(cmd *cobra.Command, args []string) (goetl.Processor, error) {
57+
chainName, _ := cmd.Flags().GetString(flagChainName)
58+
src := args[0]
59+
60+
delegatorsReaderOpts := []delegators.ReaderOption{
61+
delegators.WithChainName(chainName),
62+
delegators.WithLogger(logger),
63+
}
64+
65+
v, err := getShares(cmd, flagMinShares)
66+
if err != nil {
67+
return nil, err
68+
}
69+
if !v.IsNil() {
70+
delegatorsReaderOpts = append(delegatorsReaderOpts, delegators.WithMinSharesFilter(v))
71+
}
72+
73+
v, err = getShares(cmd, flagMaxShares)
74+
if err != nil {
75+
return nil, err
76+
}
77+
78+
if !v.IsNil() {
79+
delegatorsReaderOpts = append(delegatorsReaderOpts, delegators.WithMaxSharesFilter(v))
80+
}
81+
82+
return delegators.NewDelegatorsReader(src, delegatorsReaderOpts...)
83+
}
84+
85+
func getShares(cmd *cobra.Command, flag string) (math.LegacyDec, error) {
86+
shares, err := cmd.Flags().GetString(flag)
87+
if err != nil {
88+
return math.LegacyDec{}, err
89+
}
90+
if shares == "" {
91+
return math.LegacyDec{}, nil
92+
}
93+
return math.LegacyNewDecFromStr(shares)
94+
}
95+
5596
func init() {
5697
extractCmd.AddCommand(extractDelegatorsCmd)
5798

5899
extractDelegatorsCmd.Flags().StringSliceP(
59100
flagHrp,
60101
"p",
61102
[]string{},
62-
"One or more Human-Readable Parts (HRPs) to append delegator addresses in the given Bech32 formats (e.g., cosmos, osmo). "+
103+
"one or more Human-Readable Parts (HRPs) to append delegator addresses in the given Bech32 formats (e.g., cosmos, osmo). "+
63104
"Can be used multiple times for different HRPs.")
105+
106+
extractDelegatorsCmd.Flags().String(flagMinShares, "", "filter delegators with minimum shares")
107+
extractDelegatorsCmd.Flags().String(flagMaxShares, "", "filter delegators with maximum shares")
64108
}

cmd/extract.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ var extractCmd = &cobra.Command{
2121
func init() {
2222
rootCmd.AddCommand(extractCmd)
2323

24-
extractCmd.PersistentFlags().StringP(flagChainName, "n", "cosmos", "Name of the chain")
25-
extractCmd.PersistentFlags().StringP(flagOutput, "o", "", "Output file (defaults to stdout)")
24+
extractCmd.PersistentFlags().StringP(flagChainName, "n", "cosmos", "name of the chain")
25+
extractCmd.PersistentFlags().StringP(flagOutput, "o", "", "output file (defaults to stdout)")
2626
}
2727

2828
func newCSVWriter(cmd *cobra.Command, _ []string) (goetl.Processor, error) {

cmd/root.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,5 @@ func Execute() {
4242
}
4343

4444
func init() {
45-
rootCmd.PersistentFlags().String(flagLogLevel, "info", "The logging level (trace|debug|info|warn|error|fatal|panic)")
45+
rootCmd.PersistentFlags().String(flagLogLevel, "info", "logging level (trace|debug|info|warn|error|fatal|panic)")
4646
}

cmd/version.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,6 @@ var versionCmd = &cobra.Command{
5252
func init() {
5353
rootCmd.AddCommand(versionCmd)
5454

55-
versionCmd.Flags().Bool(flagLong, false, "Print long version information")
56-
versionCmd.Flags().StringP(flagFormat, "f", "text", "Output format (text|json)")
55+
versionCmd.Flags().Bool(flagLong, false, "print long version information")
56+
versionCmd.Flags().StringP(flagFormat, "f", "text", "output format (text|json)")
5757
}

pkg/delegators/reader.go

+63-11
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,60 @@ import (
2323
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
2424
)
2525

26+
type ReaderOption func(*delegatorsReader) error
27+
28+
func WithChainName(chainName string) ReaderOption {
29+
return func(r *delegatorsReader) error {
30+
r.chainName = chainName
31+
return nil
32+
}
33+
}
34+
35+
func WithLogger(logger log.Logger) ReaderOption {
36+
return func(r *delegatorsReader) error {
37+
r.logger = logger
38+
return nil
39+
}
40+
}
41+
42+
func WithMinSharesFilter(minShares math.LegacyDec) ReaderOption {
43+
return func(r *delegatorsReader) error {
44+
r.minSharesFilter = minShares
45+
return nil
46+
}
47+
}
48+
49+
func WithMaxSharesFilter(maxShares math.LegacyDec) ReaderOption {
50+
return func(r *delegatorsReader) error {
51+
r.maxSharesFilter = maxShares
52+
return nil
53+
}
54+
}
55+
2656
type delegatorsReader struct {
27-
chainName string
28-
src string
29-
logger log.Logger
30-
closer io.Closer
57+
chainName string
58+
src string
59+
logger log.Logger
60+
closer io.Closer
61+
minSharesFilter math.LegacyDec
62+
maxSharesFilter math.LegacyDec
3163
}
3264

3365
// NewDelegatorsReader returns a new Reader that reads delegators from a blockchain data stores.
34-
func NewDelegatorsReader(chainName, src string, logger log.Logger) (goetl.Processor, error) {
35-
return &delegatorsReader{
36-
chainName: chainName,
66+
func NewDelegatorsReader(src string, options ...ReaderOption) (goetl.Processor, error) {
67+
r := &delegatorsReader{
68+
chainName: "mystery",
3769
src: src,
38-
logger: logger,
39-
}, nil
70+
logger: log.NewNopLogger(),
71+
}
72+
73+
for _, option := range options {
74+
if err := option(r); err != nil {
75+
return nil, err
76+
}
77+
}
78+
79+
return r, nil
4080
}
4181

4282
func (r *delegatorsReader) ProcessData(_ etldata.Payload, outputChan chan etldata.Payload, killChan chan error) {
@@ -68,7 +108,13 @@ func (r *delegatorsReader) ProcessData(_ etldata.Payload, outputChan chan etldat
68108

69109
err = iterateAllAddresses(ctx, keepers.Bank, func(addr sdk.AccAddress) (stop bool) {
70110
delegations := lo.RejectMap(validators,
71-
toDelegations(ctx, addr, r.logger, keepers.Staking, killChan))
111+
extractDelegations(ctx, addr, r.logger, keepers.Staking, killChan))
112+
shares := lo.Reduce(delegations, computeShares(), math.LegacyZeroDec())
113+
114+
if (!r.maxSharesFilter.IsNil() && shares.GT(r.maxSharesFilter)) ||
115+
(!r.minSharesFilter.IsNil() && shares.LT(r.minSharesFilter)) {
116+
return false
117+
}
72118

73119
for _, delegation := range delegations {
74120
payload := Delegation{
@@ -127,7 +173,7 @@ func iterateAllAddresses(ctx context.Context, bankKeeper bankkeeper.BaseKeeper,
127173
return err
128174
}
129175

130-
func toDelegations(
176+
func extractDelegations(
131177
ctx context.Context, address sdk.AccAddress, logger log.Logger, stakingKeeper *stakingkeeper.Keeper, killChan chan error,
132178
) func(item stakingtypes.Validator, index int) (stakingtypes.Delegation, bool) {
133179
return func(item stakingtypes.Validator, _ int) (stakingtypes.Delegation, bool) {
@@ -152,6 +198,12 @@ func toDelegations(
152198
}
153199
}
154200

201+
func computeShares() func(acc math.LegacyDec, delegation stakingtypes.Delegation, _ int) math.LegacyDec {
202+
return func(acc math.LegacyDec, delegation stakingtypes.Delegation, _ int) math.LegacyDec {
203+
return acc.Add(delegation.Shares)
204+
}
205+
}
206+
155207
func guessPrefixFromValoper(valoper string) (string, error) {
156208
if idx := strings.Index(valoper, "valoper"); idx != -1 {
157209
return valoper[:idx], nil

0 commit comments

Comments
 (0)