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

Make sure the operator quorum events are all fetched #361

Merged
merged 4 commits into from
Mar 19, 2024
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
42 changes: 32 additions & 10 deletions disperser/dataapi/subgraph/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,12 +219,23 @@ func (a *api) QueryOperatorAddedToQuorum(ctx context.Context, startBlock, endBlo
"blockNumber_gt": graphql.Int(startBlock - 1),
"blockNumber_lt": graphql.Int(endBlock + 1),
}
query := new(queryOperatorAddedToQuorum)
err := a.operatorStateGql.Query(ctx, &query, variables)
if err != nil {
return nil, err
skip := 0
result := new(queryOperatorAddedToQuorum)
addedToQuorums := make([]*OperatorQuorum, 0)
for {
variables["first"] = graphql.Int(maxEntriesPerQuery)
variables["skip"] = graphql.Int(skip)
err := a.operatorStateGql.Query(ctx, &result, variables)
if err != nil {
return nil, err
}
if len(result.OperatorAddedToQuorum) == 0 {
break
}
addedToQuorums = append(addedToQuorums, result.OperatorAddedToQuorum...)
skip += maxEntriesPerQuery
}
return query.OperatorAddedToQuorum, nil
return addedToQuorums, nil
}

// QueryOperatorRemovedFromQuorum finds operators' quorum opt-out history in range [startBlock, endBlock].
Expand All @@ -236,10 +247,21 @@ func (a *api) QueryOperatorRemovedFromQuorum(ctx context.Context, startBlock, en
"blockNumber_gt": graphql.Int(startBlock - 1),
"blockNumber_lt": graphql.Int(endBlock + 1),
}
query := new(queryOperatorRemovedFromQuorum)
err := a.operatorStateGql.Query(ctx, &query, variables)
if err != nil {
return nil, err
skip := 0
result := new(queryOperatorRemovedFromQuorum)
removedFromQuorums := make([]*OperatorQuorum, 0)
for {
variables["first"] = graphql.Int(maxEntriesPerQuery)
variables["skip"] = graphql.Int(skip)
err := a.operatorStateGql.Query(ctx, &result, variables)
if err != nil {
return nil, err
}
if len(result.OperatorRemovedFromQuorum) == 0 {
break
}
removedFromQuorums = append(removedFromQuorums, result.OperatorRemovedFromQuorum...)
skip += maxEntriesPerQuery
}
return query.OperatorRemovedFromQuorum, nil
return removedFromQuorums, nil
}
14 changes: 8 additions & 6 deletions disperser/dataapi/subgraph/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@ type (
TransactionHash graphql.String
}
OperatorQuorum struct {
Id graphql.String
Operator graphql.String
QuorumNumbers graphql.String
BlockNumber graphql.String
Id graphql.String
Operator graphql.String
QuorumNumbers graphql.String
BlockNumber graphql.String
BlockTimestamp graphql.String
}
BatchNonSigningOperatorIds struct {
NonSigning struct {
Expand All @@ -54,6 +55,7 @@ type (
OperatorId graphql.String `graphql:"operatorId"`
} `graphql:"nonSigners"`
} `graphql:"nonSigning"`
BlockNumber graphql.String
}
SocketUpdates struct {
Socket graphql.String
Expand Down Expand Up @@ -102,9 +104,9 @@ type (
Operator IndexedOperatorInfo `graphql:"operator(id: $id)"`
}
queryOperatorAddedToQuorum struct {
OperatorAddedToQuorum []*OperatorQuorum `graphql:"operatorAddedToQuorums(orderBy: blockTimestamp, where: {and: [{blockNumber_gt: $blockNumber_gt}, {blockNumber_lt: $blockNumber_lt}]})"`
OperatorAddedToQuorum []*OperatorQuorum `graphql:"operatorAddedToQuorums(first: $first, skip: $skip, orderBy: blockTimestamp, where: {and: [{blockNumber_gt: $blockNumber_gt}, {blockNumber_lt: $blockNumber_lt}]})"`
}
queryOperatorRemovedFromQuorum struct {
OperatorRemovedFromQuorum []*OperatorQuorum `graphql:"operatorRemovedFromQuorums(orderBy: blockTimestamp, where: {and: [{blockNumber_gt: $blockNumber_gt}, {blockNumber_lt: $blockNumber_lt}]})"`
OperatorRemovedFromQuorum []*OperatorQuorum `graphql:"operatorRemovedFromQuorums(first: $first, skip: $skip, orderBy: blockTimestamp, where: {and: [{blockNumber_gt: $blockNumber_gt}, {blockNumber_lt: $blockNumber_lt}]})"`
}
)
38 changes: 32 additions & 6 deletions disperser/dataapi/subgraph_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,10 @@ type (
TransactionHash []byte
}
OperatorQuorum struct {
Operator string
QuorumNumbers []byte
BlockNumber uint32
Operator string
QuorumNumbers []byte
BlockNumber uint32
BlockTimestamp uint64
}
OperatorQuorumEvents struct {
// AddedToQuorum is mapping from operator address to a list of sorted events
Expand All @@ -79,6 +80,7 @@ type (
Count int
}
BatchNonSigningInfo struct {
BlockNumber uint32
QuorumNumbers []uint8
ReferenceBlockNumber uint32
// The operatorIds of nonsigners for the batch.
Expand Down Expand Up @@ -358,10 +360,29 @@ func parseOperatorQuorum(operatorQuorum []*subgraph.OperatorQuorum) ([]*Operator
if err != nil {
return nil, err
}
blockTimestamp, err := strconv.ParseUint(string(opq.BlockTimestamp), 10, 64)
if err != nil {
return nil, err
}
if len(opq.QuorumNumbers) < 2 || len(opq.QuorumNumbers)%2 != 0 {
return nil, fmt.Errorf("the QuorumNumbers is expected to start with 0x and have an even length, QuorumNumbers: %s", string(opq.QuorumNumbers))
}
// The quorum numbers string starts with "0x", so we should skip it.
quorumStr := string(opq.QuorumNumbers)[2:]
quorumNumbers := make([]byte, 0)
for i := 0; i < len(quorumStr); i += 2 {
pair := quorumStr[i : i+2]
quorum, err := strconv.Atoi(pair)
if err != nil {
return nil, err
}
quorumNumbers = append(quorumNumbers, uint8(quorum))
}
parsed[i] = &OperatorQuorum{
Operator: string(opq.Operator),
QuorumNumbers: []byte(opq.QuorumNumbers),
BlockNumber: uint32(blockNum),
Operator: string(opq.Operator),
QuorumNumbers: quorumNumbers,
BlockNumber: uint32(blockNum),
BlockTimestamp: blockTimestamp,
}
}
// Sort the quorum events by ascending order of block number.
Expand All @@ -387,12 +408,17 @@ func convertNonSigningInfo(infoGql *subgraph.BatchNonSigningInfo) (*BatchNonSign
if err != nil {
return nil, err
}
confirmBlockNum, err := strconv.ParseUint(string(infoGql.BlockNumber), 10, 64)
if err != nil {
return nil, err
}
nonSigners := make([]string, len(infoGql.NonSigning.NonSigners))
for i, nonSigner := range infoGql.NonSigning.NonSigners {
nonSigners[i] = string(nonSigner.OperatorId)
}

return &BatchNonSigningInfo{
BlockNumber: uint32(confirmBlockNum),
QuorumNumbers: quorums,
ReferenceBlockNumber: uint32(blockNum),
NonSigners: nonSigners,
Expand Down
61 changes: 33 additions & 28 deletions disperser/dataapi/subgraph_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,36 +121,42 @@ var (

operatorAddedToQuorum = []*subgraph.OperatorQuorum{
{
Operator: "operator-2",
QuorumNumbers: "2",
BlockNumber: "82",
Operator: "operator-2",
QuorumNumbers: "0x02",
BlockNumber: "82",
BlockTimestamp: "1702666070",
},
{
Operator: "operator-1",
QuorumNumbers: "2",
BlockNumber: "82",
Operator: "operator-1",
QuorumNumbers: "0x02",
BlockNumber: "82",
BlockTimestamp: "1702666070",
},
{
Operator: "operator-1",
QuorumNumbers: "01",
BlockNumber: "80",
Operator: "operator-1",
QuorumNumbers: "0x01",
BlockNumber: "80",
BlockTimestamp: "1702666046",
},
}
operatorRemovedFromQuorum = []*subgraph.OperatorQuorum{
{
Operator: "operator-1",
QuorumNumbers: "0",
BlockNumber: "81",
Operator: "operator-1",
QuorumNumbers: "0x00",
BlockNumber: "81",
BlockTimestamp: "1702666058",
},
{
Operator: "operator-2",
QuorumNumbers: "2",
BlockNumber: "83",
Operator: "operator-2",
QuorumNumbers: "0x02",
BlockNumber: "83",
BlockTimestamp: "1702666082",
},
{
Operator: "operator-1",
QuorumNumbers: "1",
BlockNumber: "83",
Operator: "operator-1",
QuorumNumbers: "0x01",
BlockNumber: "83",
BlockTimestamp: "1702666082",
},
}

Expand Down Expand Up @@ -184,6 +190,7 @@ var (
},
},
},
BlockNumber: "83",
},
{
BatchId: "0",
Expand Down Expand Up @@ -211,6 +218,7 @@ var (
},
},
},
BlockNumber: "82",
},
}

Expand Down Expand Up @@ -527,23 +535,20 @@ func TestQueryOperatorQuorumEvent(t *testing.T) {
assert.Equal(t, 2, len(added1))
assert.Equal(t, "operator-1", added1[0].Operator)
assert.Equal(t, uint32(80), added1[0].BlockNumber)
assert.Equal(t, 2, len(added1[0].QuorumNumbers))
// Note: the quorumId is 48 not 01 is because the string "01" is in UTF-8
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

previous assumption wasn't right; based on actual subgraph data, it's just a hex string starting with "0x".

// encoding (the default in golang), and it corresponding to 48 in decimal.
assert.Equal(t, uint8(48), added1[0].QuorumNumbers[0])
assert.Equal(t, uint8(49), added1[0].QuorumNumbers[1])
assert.Equal(t, 1, len(added1[0].QuorumNumbers))
assert.Equal(t, uint8(1), added1[0].QuorumNumbers[0])
assert.Equal(t, "operator-1", added1[1].Operator)
assert.Equal(t, uint32(82), added1[1].BlockNumber)
assert.Equal(t, 1, len(added1[1].QuorumNumbers))
assert.Equal(t, uint8(50), added1[1].QuorumNumbers[0])
assert.Equal(t, uint8(2), added1[1].QuorumNumbers[0])
// Quorum events for operator-2.
added2, ok := addedMap["operator-2"]
assert.True(t, ok)
assert.Equal(t, 1, len(added2))
assert.Equal(t, "operator-2", added2[0].Operator)
assert.Equal(t, uint32(82), added2[0].BlockNumber)
assert.Equal(t, 1, len(added2[0].QuorumNumbers))
assert.Equal(t, uint8(50), added2[0].QuorumNumbers[0])
assert.Equal(t, uint8(2), added2[0].QuorumNumbers[0])

removedMap := result.RemovedFromQuorum
assert.Equal(t, 2, len(removedMap))
Expand All @@ -554,17 +559,17 @@ func TestQueryOperatorQuorumEvent(t *testing.T) {
assert.Equal(t, "operator-1", removed1[0].Operator)
assert.Equal(t, uint32(81), removed1[0].BlockNumber)
assert.Equal(t, 1, len(removed1[0].QuorumNumbers))
assert.Equal(t, uint8(48), removed1[0].QuorumNumbers[0])
assert.Equal(t, uint8(0), removed1[0].QuorumNumbers[0])
assert.Equal(t, "operator-1", removed1[1].Operator)
assert.Equal(t, uint32(83), removed1[1].BlockNumber)
assert.Equal(t, 1, len(removed1[1].QuorumNumbers))
assert.Equal(t, uint8(49), removed1[1].QuorumNumbers[0])
assert.Equal(t, uint8(1), removed1[1].QuorumNumbers[0])
// Quorum events for operator-2.
removed2, ok := removedMap["operator-2"]
assert.True(t, ok)
assert.Equal(t, 1, len(removed2))
assert.Equal(t, "operator-2", removed2[0].Operator)
assert.Equal(t, uint32(83), removed2[0].BlockNumber)
assert.Equal(t, 1, len(removed2[0].QuorumNumbers))
assert.Equal(t, uint8(50), removed2[0].QuorumNumbers[0])
assert.Equal(t, uint8(2), removed2[0].QuorumNumbers[0])
}
Loading