Skip to content

Commit

Permalink
Address review milestone 2 (#355)
Browse files Browse the repository at this point in the history
* add configurable event threshold

* Add natural language desc on event parsing
  • Loading branch information
mikiquantum authored Jun 28, 2023
1 parent ec500ca commit 7e3e5ad
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 10 deletions.
63 changes: 62 additions & 1 deletion registry/REGISTRY.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,68 @@ By leveraging the on-chain metadata, GSRPC is more robust to changes on types, a

This registry can be used afterwards to decode data read from live chains (events & extrinsics).

## Usage
## How to parse events and its types
First we instantiate the API with the client node and open a connection:
```go
testURL := "wss://fullnode.parachain.centrifuge.io" // Your endpoint
api, err := gsrpc.NewSubstrateAPI(testURL)

if err != nil {
log.Printf("Couldn't connect to '%s': %s\n", testURL, err)
return
}
```
Then we instantiate the Event Retriever logic which internally creates a new EventRegistry reading from the target metadata of the connected chain. We pass as well the state RPC so the storage API is available:
```go
retriever, err := NewDefaultEventRetriever(state.NewEventProvider(api.RPC.State), api.RPC.State)

if err != nil {
log.Printf("Couldn't create event retriever: %s", err)
return
}
```
At this point what we need is a block hash to read the events within. In this example we get the latest block header and the correspondent block hash out of the block number:
```go
header, err := api.RPC.Chain.GetHeaderLatest()

if err != nil {
log.Printf("Couldn't get latest header for '%s': %s\n", testURL, err)
return
}

blockHash, err := api.RPC.Chain.GetBlockHash(uint64(header.Number))

if err != nil {
log.Printf("Couldn't retrieve blockHash for '%s', block number %d: %s\n", testURL, header.Number, err)
return
}
```
Finally, we just use the retriever function to read all the events in that block based on the chain metadata loaded in the event registry:
```go
events, err := retriever.GetEvents(blockHash)

if err != nil {
log.Printf("Couldn't retrieve events for '%s', block number %d: %s\n", testURL, header.Number, err)
return
}

log.Printf("Found %d events for '%s', at block number %d.\n", len(events), testURL, header.Number)

// Example of the events returned structure
for _, event := range events {
log.Printf("Event ID: %x \n", event.EventID)
log.Printf("Event Name: %s \n", event.Name)
log.Printf("Event Fields Count: %d \n", len(event.Fields))
for k, v := range event.Fields {
log.Printf("Field Name: %s \n", k)
log.Printf("Field Type: %v \n", reflect.TypeOf(v))
log.Printf("Field Value: %v \n", v)
}
}

```

## Extended Usage
Since docs get outdated fairly quick, here are links to tests that will always be up-to-date.
### Populate Call, Error & Events Registries
[Browse me](registry_test.go)
Expand Down
12 changes: 9 additions & 3 deletions registry/retriever/event_retriever_live_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ package retriever

import (
"log"
"os"
"strconv"
"sync"
"testing"

Expand All @@ -21,13 +23,17 @@ var (
}
)

const maxRetrievedEvents = 10000

func TestLive_EventRetriever_GetEvents(t *testing.T) {
t.Parallel()

var wg sync.WaitGroup

eventsThreshold, err := strconv.Atoi(os.Getenv("GSRPC_LIVE_TEST_EVENTS_THRESHOLD"))
if err != nil {
eventsThreshold = 50
log.Printf("Env Var GSRPC_LIVE_TEST_EVENTS_THRESHOLD not set, defaulting to %d", eventsThreshold)
}

for _, testURL := range eventTestURLs {
testURL := testURL

Expand Down Expand Up @@ -78,7 +84,7 @@ func TestLive_EventRetriever_GetEvents(t *testing.T) {

eventsCount += len(events)

if eventsCount > maxRetrievedEvents {
if eventsCount > eventsThreshold {
log.Printf("Retrieved a total of %d events for '%s', last block number %d. Stopping now.\n", eventsCount, testURL, header.Number)

return
Expand Down
18 changes: 12 additions & 6 deletions registry/retriever/extrinsic_retriever_live_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ package retriever
import (
"errors"
"log"
"os"
"strconv"
"sync"
"testing"
"time"
Expand Down Expand Up @@ -63,18 +65,24 @@ func TestLive_ExtrinsicRetriever_GetExtrinsics(t *testing.T) {

var wg sync.WaitGroup

extrinsicsThreshold, err := strconv.Atoi(os.Getenv("GSRPC_LIVE_TEST_EXTRINSICS_THRESHOLD"))
if err != nil {
extrinsicsThreshold = 50
log.Printf("Env Var GSRPC_LIVE_TEST_EXTRINSICS_THRESHOLD not set, defaulting to %d", extrinsicsThreshold)
}

for _, c := range extTestChains {
c := c

wg.Add(1)

go c.GetTestFn()(&wg)
go c.GetTestFn()(&wg, extrinsicsThreshold)
}

wg.Wait()
}

type testFn func(wg *sync.WaitGroup)
type testFn func(wg *sync.WaitGroup, extrinsicsThreshold int)

type testFnProvider interface {
GetTestFn() testFn
Expand All @@ -88,10 +96,8 @@ type testChain[
url string
}

const maxRetrievedExtrinsics = 1000

func (t *testChain[A, S, P]) GetTestFn() testFn {
return func(wg *sync.WaitGroup) {
return func(wg *sync.WaitGroup, extrinsicsThreshold int) {
defer wg.Done()

testURL := t.url
Expand Down Expand Up @@ -152,7 +158,7 @@ func (t *testChain[A, S, P]) GetTestFn() testFn {

extrinsicsCount += len(extrinsics)

if extrinsicsCount >= maxRetrievedExtrinsics {
if extrinsicsCount >= extrinsicsThreshold {
log.Printf("Retrieved a total of %d extrinsics for '%s', last block number %d. Stopping now.\n", extrinsicsCount, testURL, header.Number)

return
Expand Down

0 comments on commit 7e3e5ad

Please sign in to comment.