-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(cannon): Add Blockprint Block Classification Deriving (#227)
* feat(cannon): Add Blockprint Block Classification Deriving * refactor: Simplify BlocksPerClient function * feat(event): add blockprint block classification event * Merge master * refactor(block_classification): Remove unnecessary log statement * refactor: Add sleep to avoid API hammering * fix: Correct client name for Grandine
- Loading branch information
Showing
30 changed files
with
3,179 additions
and
1,842 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package blockprint | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
"net/http" | ||
) | ||
|
||
type Client struct { | ||
endpoint string | ||
httpClient *http.Client | ||
headers map[string]string | ||
} | ||
|
||
func NewClient(endpoint string, headers map[string]string) *Client { | ||
return &Client{ | ||
endpoint: endpoint, | ||
httpClient: http.DefaultClient, | ||
headers: headers, | ||
} | ||
} | ||
|
||
func (c *Client) get(ctx context.Context, path string) (json.RawMessage, error) { | ||
req, err := http.NewRequestWithContext(ctx, "GET", c.endpoint+path, http.NoBody) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// Set headers from c.headers | ||
for k, v := range c.headers { | ||
req.Header.Set(k, v) | ||
} | ||
|
||
rsp, err := c.httpClient.Do(req) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
defer rsp.Body.Close() | ||
|
||
if rsp.StatusCode != http.StatusOK { | ||
return nil, fmt.Errorf("status code: %d", rsp.StatusCode) | ||
} | ||
|
||
data, err := io.ReadAll(rsp.Body) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
data = bytes.TrimPrefix(data, []byte("\xef\xbb\xbf")) | ||
|
||
resp := new(json.RawMessage) | ||
if err := json.Unmarshal(data, &resp); err != nil { | ||
return nil, err | ||
} | ||
|
||
return *resp, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package blockprint | ||
|
||
type ProbabilityMap map[ClientName]float64 | ||
|
||
type ClientName string | ||
|
||
var ( | ||
ClientNameUnknown = ClientName("Unknown") | ||
ClientNameUncertain = ClientName("Uncertain") | ||
ClientNamePrysm = ClientName("Prysm") | ||
ClientNameLighthouse = ClientName("Lighthouse") | ||
ClientNameLodestar = ClientName("Lodestar") | ||
ClientNameNimbus = ClientName("Nimbus") | ||
ClientNameTeku = ClientName("Teku") | ||
ClientNameGrandine = ClientName("Grandine") | ||
) | ||
|
||
func (p ProbabilityMap) safeGet(name ClientName) float64 { | ||
if p[name] == 0 { | ||
return 0 | ||
} | ||
|
||
return p[name] | ||
} | ||
|
||
func (p ProbabilityMap) Prysm() float64 { | ||
return p.safeGet(ClientNamePrysm) | ||
} | ||
|
||
func (p ProbabilityMap) Lighthouse() float64 { | ||
return p.safeGet(ClientNameLighthouse) | ||
} | ||
|
||
func (p ProbabilityMap) Lodestar() float64 { | ||
return p.safeGet(ClientNameLodestar) | ||
} | ||
|
||
func (p ProbabilityMap) Nimbus() float64 { | ||
return p.safeGet(ClientNameNimbus) | ||
} | ||
|
||
func (p ProbabilityMap) Teku() float64 { | ||
return p.safeGet(ClientNameTeku) | ||
} | ||
|
||
func (p ProbabilityMap) Grandine() float64 { | ||
return p.safeGet(ClientNameGrandine) | ||
} | ||
|
||
func (p ProbabilityMap) Uncertain() float64 { | ||
return p.safeGet(ClientNameUncertain) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package blockprint | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
|
||
"github.com/attestantio/go-eth2-client/spec/phase0" | ||
) | ||
|
||
type ProposersBlocksResponse struct { | ||
//nolint:tagliatelle // Defined by API. | ||
ProposerIndex uint64 `json:"proposer_index"` | ||
Slot uint64 `json:"slot"` | ||
//nolint:tagliatelle // Defined by API. | ||
BestGuessSingle ClientName `json:"best_guess_single"` | ||
//nolint:tagliatelle // Defined by API. | ||
BestGuessMulti string `json:"best_guess_multi"` | ||
//nolint:tagliatelle // Defined by API. | ||
ProbabilityMap *ProbabilityMap `json:"probability_map"` | ||
} | ||
|
||
func (c *Client) BlocksRange(ctx context.Context, startSlot phase0.Slot, endSlot ...phase0.Slot) ([]*ProposersBlocksResponse, error) { | ||
var path string | ||
if len(endSlot) > 0 { | ||
path = fmt.Sprintf("/blocks/%d/%d", startSlot, endSlot[0]) | ||
} else { | ||
path = fmt.Sprintf("/blocks/%d", startSlot) | ||
} | ||
|
||
data, err := c.get(ctx, path) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var result []*ProposersBlocksResponse | ||
|
||
err = json.Unmarshal(data, &result) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return result, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package blockprint | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
) | ||
|
||
type BlocksPerClientResponse struct { | ||
//nolint:tagliatelle // Defined by API. | ||
Uncertain uint64 `json:"Uncertain"` | ||
//nolint:tagliatelle // Defined by API. | ||
Lighthouse uint64 `json:"Lighthouse"` | ||
//nolint:tagliatelle // Defined by API. | ||
Lodestar uint64 `json:"Lodestar"` | ||
//nolint:tagliatelle // Defined by API. | ||
Nimbus uint64 `json:"Nimbus"` | ||
//nolint:tagliatelle // Defined by API. | ||
Other uint64 `json:"Other"` | ||
//nolint:tagliatelle // Defined by API. | ||
Prysm uint64 `json:"Prysm"` | ||
//nolint:tagliatelle // Defined by API. | ||
Teku uint64 `json:"Teku"` | ||
//nolint:tagliatelle // Defined by API. | ||
Grandine uint64 `json:"Grandine"` | ||
} | ||
|
||
type SyncStatusResponse struct { | ||
//nolint:tagliatelle // Defined by API. | ||
GreatestBlockSlot uint64 `json:"greatest_block_slot"` | ||
Synced bool `json:"synced"` | ||
} | ||
|
||
func (c *Client) BlocksPerClient(ctx context.Context, startEpoch, endEpoch string) (*BlocksPerClientResponse, error) { | ||
data, err := c.get(ctx, "/blocks_per_client/"+startEpoch+"/"+endEpoch) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var result BlocksPerClientResponse | ||
|
||
err = json.Unmarshal(data, &result) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &result, nil | ||
} | ||
|
||
func (c *Client) SyncStatus(ctx context.Context) (*SyncStatusResponse, error) { | ||
data, err := c.get(ctx, "/sync/status") | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var result SyncStatusResponse | ||
|
||
err = json.Unmarshal(data, &result) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &result, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.