Skip to content

Commit

Permalink
Merge pull request #5 from drand/refactor
Browse files Browse the repository at this point in the history
Integrating drand interfaces into drand-cli codebase
  • Loading branch information
AnomalRoil authored Aug 13, 2024
2 parents da4b07e + bd9ac19 commit 5c1e30c
Show file tree
Hide file tree
Showing 44 changed files with 732 additions and 643 deletions.
7 changes: 1 addition & 6 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,9 @@ issues:
- path: internal/lib
linters:
- forbidigo # we use Println in our UX
- path: internal/drand-cli
linters:
- forbidigo # we use Println in our UX
- goconst # we re-use some strings in our flags
- path: client/http
text: "unexported-return"
run:
skip-dirs:
exclude-dirs:
- demo
- test

Expand Down
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
.PHONY: drand-relay-gossip client-tool build clean

build: drand-relay-gossip client-tool

clean:
rm -f ./drand-relay-gossip ./drand-cli

drand-relay-gossip:
go build -o drand-relay-gossip ./gossip-relay/main.go

Expand Down
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,37 @@ This repo contains most notably:
- a client CLI tool to fetch and verify drand beacons from the various available sources in your terminal
- a gossipsub relay to relay drand beacons on gossipsub

# Migration from drand/drand

Prior to drand V2 release, the drand client code lived in the drand/drand repo. Since its V2 release, the drand daemon code aims at being more minimalist and having as few dependencies as possible.
Most notably this meant removing the libp2p code that was exclusively used for Gossip relays and Gossip client, and also trimming down the amount of HTTP-related code.

From now on, this repo is meant to provide the Go Client code to interact with drand, query drand beacons and verify them through either the HTTP or the Gossip relays.

Note that drand does not provide public gRPC endpoints since ~2020, therefore the gRPC client code has been moved to the internal package of the relays (to allow relays to directly interface with a working daemon using gRPC).

There are relatively few changes to the public APIs of the client code and simply using the `drand/go-clients/http` packages should be enough.
We recommend using `go-doc` to see the usage documentation and examples.

## Most notable changes from the drand/drand V1 APIs

The `Result` interface now follows the Protobuf getter format:
```
Result.Round() -> Result.GetRound()
Result.Randomness() -> Result.GetRandomness()
Result.Signature() -> Result.GetSignature()
Result.PreviousSignature() -> Result.GetPreviousSignature()
```
meaning `PublicRandResponse` now satisfies directly the `Result` interface.

The HTTP client now returns a concrete type and doesn't need to be cast to a HTTP client to use e.g. `SetUserAgent`.

The client option `WithVerifiedResult` was renamed `WithTrustedResult`, to properly convey its function.

Note also that among other packages you might be using in the `github.com/drand/drand/v2` packages,
the `crypto.GetSchemeByIDWithDefault` function was renamed `crypto.GetSchemeByID`;
and the `Beacon` struct now lives in the `github.com/drand/drand/v2/common` package rather than in the `chain` one.

---

### License
Expand Down
26 changes: 13 additions & 13 deletions client/aggregator.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"sync"
"time"

"github.com/drand/drand/v2/common/client"
"github.com/drand/drand/v2/common/log"
"github.com/drand/go-clients/drand"
)

const (
Expand All @@ -24,7 +24,7 @@ const (
// is passed, a `watch` will be run on the watch client in the absence of external watchers,
// which will swap watching over to the main client. If no watch client is set and autowatch is off
// then a single watch will only run when an external watch is requested.
func newWatchAggregator(l log.Logger, c, wc client.Client, autoWatch bool, autoWatchRetry time.Duration) *watchAggregator {
func newWatchAggregator(l log.Logger, c, wc drand.Client, autoWatch bool, autoWatchRetry time.Duration) *watchAggregator {
if autoWatchRetry == 0 {
autoWatchRetry = defaultAutoWatchRetry
}
Expand All @@ -41,12 +41,12 @@ func newWatchAggregator(l log.Logger, c, wc client.Client, autoWatch bool, autoW

type subscriber struct {
ctx context.Context
c chan client.Result
c chan drand.Result
}

type watchAggregator struct {
client.Client
passiveClient client.Client
drand.Client
passiveClient drand.Client
autoWatch bool
autoWatchRetry time.Duration
log log.Logger
Expand Down Expand Up @@ -82,7 +82,7 @@ func (c *watchAggregator) startAutoWatch(full bool) {
c.cancelAutoWatch = cancel
go func() {
for {
var results <-chan client.Result
var results <-chan drand.Result
if full {
results = c.Watch(ctx)
} else if c.passiveClient != nil {
Expand Down Expand Up @@ -118,7 +118,7 @@ func (c *watchAggregator) startAutoWatch(full bool) {

// passiveWatch is a degraded form of watch, where watch only hits the 'passive client'
// unless distribution is actually needed.
func (c *watchAggregator) passiveWatch(ctx context.Context) <-chan client.Result {
func (c *watchAggregator) passiveWatch(ctx context.Context) <-chan drand.Result {
c.subscriberLock.Lock()
defer c.subscriberLock.Unlock()

Expand All @@ -127,7 +127,7 @@ func (c *watchAggregator) passiveWatch(ctx context.Context) <-chan client.Result
return nil
}

wc := make(chan client.Result)
wc := make(chan drand.Result)
if len(c.subscribers) == 0 {
ctx, cancel := context.WithCancel(ctx)
c.cancelPassive = cancel
Expand All @@ -139,11 +139,11 @@ func (c *watchAggregator) passiveWatch(ctx context.Context) <-chan client.Result
return wc
}

func (c *watchAggregator) Watch(ctx context.Context) <-chan client.Result {
func (c *watchAggregator) Watch(ctx context.Context) <-chan drand.Result {
c.subscriberLock.Lock()
defer c.subscriberLock.Unlock()

sub := subscriber{ctx, make(chan client.Result, aggregatorWatchBuffer)}
sub := subscriber{ctx, make(chan drand.Result, aggregatorWatchBuffer)}
c.subscribers = append(c.subscribers, sub)

if len(c.subscribers) == 1 {
Expand All @@ -157,14 +157,14 @@ func (c *watchAggregator) Watch(ctx context.Context) <-chan client.Result {
return sub.c
}

func (c *watchAggregator) sink(in <-chan client.Result, out chan client.Result) {
func (c *watchAggregator) sink(in <-chan drand.Result, out chan drand.Result) {
defer close(out)
for range in {
continue
}
}

func (c *watchAggregator) distribute(in <-chan client.Result, cancel context.CancelFunc) {
func (c *watchAggregator) distribute(in <-chan drand.Result, cancel context.CancelFunc) {
defer cancel()
for {
c.subscriberLock.Lock()
Expand All @@ -176,7 +176,7 @@ func (c *watchAggregator) distribute(in <-chan client.Result, cancel context.Can
aCtx := c.subscribers[0].ctx
c.subscriberLock.Unlock()

var m client.Result
var m drand.Result
var ok bool

select {
Expand Down
8 changes: 4 additions & 4 deletions client/aggregator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ import (
"testing"
"time"

"github.com/drand/drand/v2/common/client"
"github.com/drand/drand/v2/common/log"
clientMock "github.com/drand/go-clients/client/mock"
"github.com/drand/go-clients/client/test/result/mock"
"github.com/drand/go-clients/drand"
)

func TestAggregatorClose(t *testing.T) {
wg := sync.WaitGroup{}
wg.Add(1)

c := &clientMock.Client{
WatchCh: make(chan client.Result),
WatchCh: make(chan drand.Result),
CloseF: func() error {
wg.Done()
return nil
Expand All @@ -38,15 +38,15 @@ func TestAggregatorPassive(t *testing.T) {
wg.Add(1)

c := &clientMock.Client{
WatchCh: make(chan client.Result, 1),
WatchCh: make(chan drand.Result, 1),
CloseF: func() error {
wg.Done()
return nil
},
}

wc := &clientMock.Client{
WatchCh: make(chan client.Result, 1),
WatchCh: make(chan drand.Result, 1),
CloseF: func() error {
return nil
},
Expand Down
27 changes: 14 additions & 13 deletions client/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@ import (

lru "github.com/hashicorp/golang-lru"

"github.com/drand/drand/v2/common/client"
"github.com/drand/go-clients/drand"

"github.com/drand/drand/v2/common/log"
)

// Cache provides a mechanism to check for rounds in the cache.
type Cache interface {
// TryGet provides a round beacon or nil if it is not cached.
TryGet(round uint64) client.Result
TryGet(round uint64) drand.Result
// Add adds an item to the cache
Add(uint64, client.Result)
Add(uint64, drand.Result)
}

// makeCache creates a cache of a given size
Expand All @@ -36,14 +37,14 @@ type typedCache struct {
}

// Add a result to the cache
func (t *typedCache) Add(round uint64, result client.Result) {
func (t *typedCache) Add(round uint64, result drand.Result) {
t.ARCCache.Add(round, result)
}

// TryGet attempts to get a result from the cache
func (t *typedCache) TryGet(round uint64) client.Result {
func (t *typedCache) TryGet(round uint64) drand.Result {
if val, ok := t.ARCCache.Get(round); ok {
return val.(client.Result)
return val.(drand.Result)
}
return nil
}
Expand All @@ -52,17 +53,17 @@ func (t *typedCache) TryGet(round uint64) client.Result {
type nilCache struct{}

// Add a result to the cache
func (*nilCache) Add(_ uint64, _ client.Result) {
func (*nilCache) Add(_ uint64, _ drand.Result) {
}

// TryGet attempts to get ar esult from the cache
func (*nilCache) TryGet(_ uint64) client.Result {
func (*nilCache) TryGet(_ uint64) drand.Result {
return nil
}

// NewCachingClient is a meta client that stores an LRU cache of
// recently fetched random values.
func NewCachingClient(l log.Logger, c client.Client, cache Cache) (client.Client, error) {
func NewCachingClient(l log.Logger, c drand.Client, cache Cache) (drand.Client, error) {
return &cachingClient{
Client: c,
cache: cache,
Expand All @@ -71,7 +72,7 @@ func NewCachingClient(l log.Logger, c client.Client, cache Cache) (client.Client
}

type cachingClient struct {
client.Client
drand.Client

cache Cache
log log.Logger
Expand All @@ -91,7 +92,7 @@ func (c *cachingClient) String() string {
}

// Get returns the randomness at `round` or an error.
func (c *cachingClient) Get(ctx context.Context, round uint64) (res client.Result, err error) {
func (c *cachingClient) Get(ctx context.Context, round uint64) (res drand.Result, err error) {
if val := c.cache.TryGet(round); val != nil {
return val, nil
}
Expand All @@ -102,9 +103,9 @@ func (c *cachingClient) Get(ctx context.Context, round uint64) (res client.Resul
return val, err
}

func (c *cachingClient) Watch(ctx context.Context) <-chan client.Result {
func (c *cachingClient) Watch(ctx context.Context) <-chan drand.Result {
in := c.Client.Watch(ctx)
out := make(chan client.Result)
out := make(chan drand.Result)
go func() {
for result := range in {
if ctx.Err() != nil {
Expand Down
6 changes: 3 additions & 3 deletions client/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import (
"sync"
"testing"

"github.com/drand/drand/v2/common/client"
"github.com/drand/drand/v2/common/log"
clientMock "github.com/drand/go-clients/client/mock"
"github.com/drand/go-clients/client/test/result/mock"
"github.com/drand/go-clients/drand"
)

func TestCacheGet(t *testing.T) {
Expand Down Expand Up @@ -79,7 +79,7 @@ func TestCacheGetLatest(t *testing.T) {

func TestCacheWatch(t *testing.T) {
m := clientMock.ClientWithResults(2, 6)
rc := make(chan client.Result, 1)
rc := make(chan drand.Result, 1)
m.WatchCh = rc
arcCache, err := makeCache(3)
if err != nil {
Expand Down Expand Up @@ -111,7 +111,7 @@ func TestCacheClose(t *testing.T) {
wg.Add(1)

c := &clientMock.Client{
WatchCh: make(chan client.Result),
WatchCh: make(chan drand.Result),
CloseF: func() error {
wg.Done()
return nil
Expand Down
Loading

0 comments on commit 5c1e30c

Please sign in to comment.