/
smeshers.go
123 lines (109 loc) · 3.71 KB
/
smeshers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package storagereader
import (
"context"
"fmt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"github.com/spacemeshos/explorer-backend/model"
"github.com/spacemeshos/explorer-backend/utils"
)
// CountSmeshers returns the number of smeshers matching the query.
func (s *Reader) CountSmeshers(ctx context.Context, query *bson.D, opts ...*options.CountOptions) (int64, error) {
count, err := s.db.Collection("smeshers").CountDocuments(ctx, query, opts...)
if err != nil {
return 0, fmt.Errorf("error count transactions: %w", err)
}
return count, nil
}
// GetSmeshers returns the smeshers matching the query.
func (s *Reader) GetSmeshers(ctx context.Context, query *bson.D, opts ...*options.FindOptions) ([]*model.Smesher, error) {
cursor, err := s.db.Collection("smeshers").Find(ctx, query, opts...)
if err != nil {
return nil, fmt.Errorf("error get smeshers: %w", err)
}
var smeshers []*model.Smesher
if err = cursor.All(ctx, &smeshers); err != nil {
return nil, fmt.Errorf("error decode smeshers: %w", err)
}
return smeshers, nil
}
// GetEpochSmeshers returns the smeshers for specific epoch
func (s *Reader) CountEpochSmeshers(ctx context.Context, query *bson.D) (int64, error) {
count, err := s.db.Collection("smeshers").CountDocuments(ctx, query)
if err != nil {
return 0, fmt.Errorf("error get smeshers: %w", err)
}
return count, nil
}
// GetEpochSmeshers returns the smeshers for specific epoch
func (s *Reader) GetEpochSmeshers(ctx context.Context, query *bson.D, opts ...*options.FindOptions) ([]*model.Smesher, error) {
cursor, err := s.db.Collection("smeshers").Find(ctx, query, opts...)
if err != nil {
return nil, fmt.Errorf("error get smeshers: %w", err)
}
var smeshers []*model.Smesher
if err = cursor.All(ctx, &smeshers); err != nil {
return nil, fmt.Errorf("error decode smeshers: %w", err)
}
return smeshers, nil
}
// GetSmesher returns the smesher matching the query.
func (s *Reader) GetSmesher(ctx context.Context, smesherID string) (*model.Smesher, error) {
matchStage := bson.D{{Key: "$match", Value: bson.D{{Key: "id", Value: smesherID}}}}
lookupStage := bson.D{
{Key: "$lookup",
Value: bson.D{
{Key: "from", Value: "malfeasance_proofs"},
{Key: "localField", Value: "id"},
{Key: "foreignField", Value: "smesher"},
{Key: "as", Value: "proofs"},
},
},
}
cursor, err := s.db.Collection("smeshers").Aggregate(ctx, mongo.Pipeline{
matchStage,
lookupStage,
})
if err != nil {
return nil, fmt.Errorf("error get smesher `%s`: %w", smesherID, err)
}
if !cursor.Next(ctx) {
return nil, nil
}
var smesher *model.Smesher
if err = cursor.Decode(&smesher); err != nil {
return nil, fmt.Errorf("error decode smesher `%s`: %w", smesherID, err)
}
return smesher, nil
}
// CountSmesherRewards returns the number of smesher rewards matching the query.
func (s *Reader) CountSmesherRewards(ctx context.Context, smesherID string) (total, count int64, err error) {
matchStage := bson.D{{Key: "$match", Value: bson.D{{Key: "smesher", Value: smesherID}}}}
groupStage := bson.D{
{Key: "$group", Value: bson.D{
{Key: "_id", Value: ""},
{Key: "total", Value: bson.D{
{Key: "$sum", Value: "$total"},
}},
{Key: "layerReward", Value: bson.D{
{Key: "$sum", Value: "$layerReward"},
}},
{Key: "count", Value: bson.D{
{Key: "$sum", Value: 1},
}},
}},
}
cursor, err := s.db.Collection("rewards").Aggregate(ctx, mongo.Pipeline{
matchStage,
groupStage,
})
if err != nil {
return 0, 0, fmt.Errorf("error get smesher rewards: %w", err)
}
if !cursor.Next(ctx) {
return 0, 0, nil
}
doc := cursor.Current
return utils.GetAsInt64(doc.Lookup("total")), utils.GetAsInt64(doc.Lookup("count")), nil
}