Skip to content

Commit

Permalink
Merge pull request #6 from Concordium/update-go
Browse files Browse the repository at this point in the history
Implement missing endpoints
  • Loading branch information
abizjak authored Jan 30, 2024
2 parents 1301670 + cc2ecd1 commit 53e4fc9
Show file tree
Hide file tree
Showing 24 changed files with 13,276 additions and 11,786 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "concordium-grpc-api"]
path = concordium-grpc-api
url = [email protected]:Concordium/concordium-grpc-api.git
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Changelog

## Unreleased changes
- Added support for GRPC V2 `GetWinningBakersEpoch` for getting a list of bakers that won the lottery in a particular historical epoch. Only available when querying a node with version at least 6.1.
- Added support for GRPC V2 `GetFirstBlockEpoch` for getting the block hash of the first finalized block in a specified epoch. Only available when querying a node with version at least 6.1.
- Added support for GRPC V2 `GetBakerEarliestWinTime` for getting the projected earliest time at which a particular baker will be required to bake a block. Only available when querying a node with version at least 6.1.
- Added support for GRPC V2 `GetBakerRewardPeriodInfo` for getting all the bakers in the reward period of a block. Only available when querying a node with version at least 6.1.
- Added support for GRPC V2 `GetBlockCertificates` for retrieving certificates for a block supporting ConcordiumBF, i.e. a node with at least version 6.1.
1 change: 1 addition & 0 deletions concordium-grpc-api
Submodule concordium-grpc-api added at ffd3be
28 changes: 28 additions & 0 deletions v2/examples/getbakerearliestwintime/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package main

import (
"context"
"fmt"
"log"

v2 "github.com/Concordium/concordium-go-sdk/v2"
"github.com/Concordium/concordium-go-sdk/v2/pb"
)

// This example retrieves and prints projected earliest wintime of a baker.
func main() {
client, err := v2.NewClient(v2.Config{NodeAddress: "node.testnet.concordium.com:20000"})
if err != nil {
log.Fatalf("Failed to instantiate client, err: %v", err)
}

// sending empty context, can also use any other context instead.
resp, err := client.GetBakerEarliestWinTime(context.TODO(), &pb.BakerId{
Value: 1,
})
if err != nil {
log.Fatalf("failed to get wintime, err: %v", err)
}

fmt.Println("wintime: ", resp)
}
36 changes: 36 additions & 0 deletions v2/examples/getbakersrewardperiod/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package main

import (
"context"
"fmt"
"io"
"log"

v2 "github.com/Concordium/concordium-go-sdk/v2"
)

// This example retrieves and prints the info of the bakers in the reward period of a block.
func main() {
client, err := v2.NewClient(v2.Config{NodeAddress: "node.testnet.concordium.com:20000"})
if err != nil {
log.Fatalf("Failed to instantiate client, err: %v", err)
}

// sending empty context, can also use any other context instead.
stream, err := client.GetBakersRewardPeriod(context.TODO(), v2.BlockHashInputBest{})
if err != nil {
log.Fatalf("failed to get BakerRewardPeriodInfos, err: %v", err)
}

for err == nil {
bakerRewardPeriodInfo, err := stream.Recv()
if err != nil {
if err == io.EOF {
// All BakerRewardPeriodInfo recieved.
break
}
log.Fatalf("Could not receive BakerRewardPeriodInfo, err: %v", err)
}
fmt.Println("BakerRewardPeriodInfo: ", bakerRewardPeriodInfo)
}
}
25 changes: 25 additions & 0 deletions v2/examples/getblockcertificates/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package main

import (
"context"
"fmt"
"log"

v2 "github.com/Concordium/concordium-go-sdk/v2"
)

// This example retrieves and prints the blockcertificates of a non-genesis block.
func main() {
client, err := v2.NewClient(v2.Config{NodeAddress: "node.testnet.concordium.com:20000"})
if err != nil {
log.Fatalf("Failed to instantiate client, err: %v", err)
}

// sending empty context, can also use any other context instead.
resp, err := client.GetBlockCertificates(context.TODO(), v2.BlockHashInputBest{})
if err != nil {
log.Fatalf("failed to get certificates, err: %v", err)
}

fmt.Println("certificates: ", resp)
}
2 changes: 1 addition & 1 deletion v2/examples/getconsensusinfo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"fmt"
"log"

"github.com/Concordium/concordium-go-sdk/v2"
v2 "github.com/Concordium/concordium-go-sdk/v2"
)

// in this example we receive and print consensus info.
Expand Down
27 changes: 27 additions & 0 deletions v2/examples/getfirstblockepoch/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main

import (
"context"
"fmt"
"log"

v2 "github.com/Concordium/concordium-go-sdk/v2"
)

// This example retrieves and prints the block hash of the first finalized block in a specific epoch.
func main() {
client, err := v2.NewClient(v2.Config{NodeAddress: "node.testnet.concordium.com:20000"})
if err != nil {
log.Fatalf("Failed to instantiate client, err: %v", err)
}

// sending empty context, can also use any other context instead.
resp, err := client.GetFirstBlockEpoch(context.TODO(), v2.EpochRequestBlockHash{
BlockHash: v2.BlockHashInputLastFinal{},
})
if err != nil {
log.Fatalf("failed to get first block, err: %v", err)
}

fmt.Println("hash: ", resp)
}
39 changes: 39 additions & 0 deletions v2/examples/getwinningbakersepoch/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package main

import (
"context"
"fmt"
"io"
"log"

v2 "github.com/Concordium/concordium-go-sdk/v2"
)

// This example retrieves and prints the bakers that won the lottery in a particular historical epoch.
func main() {
client, err := v2.NewClient(v2.Config{NodeAddress: "node.testnet.concordium.com:20000"})
if err != nil {
log.Fatalf("Failed to instantiate client, err: %v", err)
}

// sending empty context, can also use any other context instead.
stream, err := client.GetWinningBakersEpoch(context.TODO(), v2.EpochRequestRelativeEpoch{
GenesisIndex: v2.GenesisIndex{Value: 3},
Epoch: v2.Epoch{Value: 5},
})
if err != nil {
log.Fatalf("failed to get winning bakers, err: %v", err)
}

for err == nil {
winningBaker, err := stream.Recv()
if err != nil {
if err == io.EOF {
// All WinningBakers recieved.
break
}
log.Fatalf("Could not receive winning baker, err: %v", err)
}
fmt.Println("Winning baker: ", winningBaker)
}
}
30 changes: 30 additions & 0 deletions v2/getbakerearliestwintime.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package v2

import (
"context"

"github.com/Concordium/concordium-go-sdk/v2/pb"
)

// GetBakerEarliestWinTime retrieves the projected earliest time at which a particular baker will be required to bake a block.
//
// - If the baker is not a baker for the current reward period, this returns a timestamp at the start of the next reward period.
// - If the baker is a baker for the current reward period, the earliest win time is projected from the current round forwward,
// assuming that each round after the last finalixed round will take the minimum block time. (If blocks take longer, or timeouts occur,
// the actual time may be later, and the reported time in subsequent queries may reflect this.)
// - At the end of an epoch (or if the baker is not projected to bake before the end of the epoch)
// the earliest win time for a (current) baker will be projected as the start of the next epoch.
// This is because the seed for the leader election is updated at the epoch boundary,
// and so the winners cannot be predicted beyond that.
//
// Note that in some circumstances the returned timestamp can be in the past, especially at the end of an epoch.
//
// This endpoint is only supported for protocol version 6 and onwards.
func (c *Client) GetBakerEarliestWinTime(ctx context.Context, req *pb.BakerId) (_ Timestamp, err error) {
timestamp, err := c.GrpcClient.GetBakerEarliestWinTime(ctx, req)
if err != nil {
return Timestamp{}, err
}

return parseTimestamp(timestamp), nil
}
17 changes: 17 additions & 0 deletions v2/getbakersrewardperiod.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package v2

import (
"context"
)

// GetBakersRewardPeriod retrieves all bakers in the reward period of a block.
//
// This endpoint is only supported for protocol version 6 and onwards.
func (c *Client) GetBakersRewardPeriod(ctx context.Context, req isBlockHashInput) (_ BakerRewardPeriodInfoStream, err error) {
stream, err := c.GrpcClient.GetBakersRewardPeriod(ctx, convertBlockHashInput(req))
if err != nil {
return BakerRewardPeriodInfoStream{}, err
}

return BakerRewardPeriodInfoStream{stream: stream}, nil
}
20 changes: 20 additions & 0 deletions v2/getblockcertificates.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package v2

import (
"context"

"github.com/Concordium/concordium-go-sdk/v2/pb"
)

// GetBlockCertificates returns the quorum certificate, a timeout certificate (if present) and epoch finalization certificate (if present)
// for a non-genesis block.
//
// This endpoint is only supported for protocol version 6 and onwards.
func (c *Client) GetBlockCertificates(ctx context.Context, req isBlockHashInput) (_ *pb.BlockCertificates, err error) {
certificates, err := c.GrpcClient.GetBlockCertificates(ctx, convertBlockHashInput(req))
if err != nil {
return &pb.BlockCertificates{}, err
}

return certificates, nil
}
29 changes: 29 additions & 0 deletions v2/getfirstblockepoch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package v2

import (
"context"
)

// GetFirstBlockEpoch retrieves the block hash of the first finalized block in a specified epoch.
//
// The following errors are possible:
// - `NOT_FOUND` if the query specifies an unknown block.
// - `UNAVAILABLE` if the query is for an epoch that is not finalized in the current genesis index, or is for a future genesis index.
// - `INVALID_ARGUMENT` if the query is for an epoch with no finalized blocks for a past genesis index.
// - `INVALID_ARGUMENT` if the input `EpochRequest` is malformed.
// - `UNIMPLEMENTED` if the endpoint is disabled on the node.
//
// This endpoint is only supported for protocol version 6 and onwards.
func (c *Client) GetFirstBlockEpoch(ctx context.Context, req isEpochRequest) (_ BlockHash, err error) {
resp, err := c.GrpcClient.GetFirstBlockEpoch(ctx, convertEpochRequest(req))
if err != nil {
return BlockHash{}, err
}

res, err := parseBlockHash(resp)
if err != nil {
return BlockHash{}, err
}

return res, nil
}
29 changes: 29 additions & 0 deletions v2/getwinningbakersepoch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package v2

import (
"context"
)

// GetWinningBakersEpoch retrieves the list of bakers that won the lottery in a particular historical epoch
// (i.e. the last finalized block is in a later epoch). This lists the winners for each round in the
// epoch, starting from the round after the last block in the previous epoch, running to
// the round before the first block in the next epoch. It also indicates if a block in each
// round was included in the finalized chain.
//
// The following error cases are possible:
// - `NOT_FOUND` if the query specifies an unknown block.
// - `UNAVAILABLE` if the query is for an epoch that is not finalized in the current genesis index, or is for a future genesis index.
// - `INVALID_ARGUMENT` if the query is for an epoch that is not finalized for a past genesis index.
// - `INVALID_ARGUMENT` if the query is for a genesis index at consensus version 0.
// - `INVALID_ARGUMENT` if the input `EpochRequest` is malformed.
// - `UNIMPLEMENTED` if the endpoint is disabled on the node.
//
// This endpoint is only supported for protocol version 6 and onwards.
func (c *Client) GetWinningBakersEpoch(ctx context.Context, req isEpochRequest) (_ WinningBakerStream, err error) {
stream, err := c.GrpcClient.GetWinningBakersEpoch(ctx, convertEpochRequest(req))
if err != nil {
return WinningBakerStream{}, err
}

return WinningBakerStream{stream: stream}, nil
}
Loading

0 comments on commit 53e4fc9

Please sign in to comment.