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

Add basic metrics #35

Merged
merged 21 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from 10 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
6 changes: 6 additions & 0 deletions api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,9 @@ func (c *Client) Contracts(ids []types.FileContractID) (resp []explorer.FileCont
err = c.c.POST("/explorer/contracts", ids, &resp)
return
}

// Metrics returns various metrics about Sia.
func (c *Client) Metrics() (resp explorer.Metrics, err error) {
err = c.c.GET("/explorer/metrics", &resp)
return
}
10 changes: 10 additions & 0 deletions api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type (
Tip() (types.ChainIndex, error)
Block(id types.BlockID) (explorer.Block, error)
BestTip(height uint64) (types.ChainIndex, error)
Metrics() (explorer.Metrics, error)
Transactions(ids []types.TransactionID) ([]explorer.Transaction, error)
Balance(address types.Address) (sc types.Currency, immatureSC types.Currency, sf uint64, err error)
UnspentSiacoinOutputs(address types.Address, offset, limit uint64) ([]explorer.SiacoinOutput, error)
Expand Down Expand Up @@ -152,6 +153,14 @@ func (s *server) explorerTipHeightHandler(jc jape.Context) {
jc.Encode(tip)
}

func (s *server) explorerMetricsHandler(jc jape.Context) {
metrics, err := s.e.Metrics()
if jc.Check("failed to get metrics", err) != nil {
return
}
jc.Encode(metrics)
}

func (s *server) explorerBlockHandler(jc jape.Context) {
var id types.BlockID
if jc.DecodeParam("id", &id) != nil {
Expand Down Expand Up @@ -312,6 +321,7 @@ func NewServer(e Explorer, cm ChainManager, s Syncer) http.Handler {

"GET /explorer/tip": srv.explorerTipHandler,
"GET /explorer/tip/:height": srv.explorerTipHeightHandler,
"GET /explorer/metrics": srv.explorerMetricsHandler,
"GET /explorer/block/:id": srv.explorerBlockHandler,
"GET /explorer/transactions/:id": srv.explorerTransactionsIDHandler,
"POST /explorer/transactions": srv.explorerTransactionsHandler,
Expand Down
13 changes: 6 additions & 7 deletions explorer/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ const (
EventTypeFoundationSubsidy = "foundation subsidy"
)

// Arbitrary data specifiers
var (
SpecifierAnnouncement = types.NewSpecifier("HostAnnouncement")
)

type eventData interface {
EventType() string
}
Expand Down Expand Up @@ -186,9 +191,6 @@ func AppliedEvents(cs consensus.State, b types.Block, cu ChainUpdate) []Event {
// handle v1 transactions
for _, txn := range b.Transactions {
relevant := relevantTxn(txn)
if len(relevant) == 0 {
continue
}

var e EventTransaction
for _, arb := range txn.ArbitraryData {
Expand All @@ -198,7 +200,7 @@ func AppliedEvents(cs consensus.State, b types.Block, cu ChainUpdate) []Event {
prefix.DecodeFrom(d)
netAddress := d.ReadString()
uk.DecodeFrom(d)
if d.Err() == nil && prefix == types.NewSpecifier("HostAnnouncement") &&
if d.Err() == nil && prefix == SpecifierAnnouncement &&
uk.Algorithm == types.SpecifierEd25519 && len(uk.Key) == len(types.PublicKey{}) {
e.HostAnnouncements = append(e.HostAnnouncements, HostAnnouncement{
PublicKey: *(*types.PublicKey)(uk.Key),
Expand All @@ -216,9 +218,6 @@ func AppliedEvents(cs consensus.State, b types.Block, cu ChainUpdate) []Event {
// handle v2 transactions
for _, txn := range b.V2Transactions() {
relevant := relevantV2Txn(txn)
if len(relevant) == 0 {
continue
}

var e EventTransaction
for _, a := range txn.Attestations {
Expand Down
6 changes: 6 additions & 0 deletions explorer/explorer.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type Store interface {
Block(id types.BlockID) (Block, error)
BestTip(height uint64) (types.ChainIndex, error)
MerkleProof(leafIndex uint64) ([]types.Hash256, error)
Metrics() (Metrics, error)
Transactions(ids []types.TransactionID) ([]Transaction, error)
UnspentSiacoinOutputs(address types.Address, offset, limit uint64) ([]SiacoinOutput, error)
UnspentSiafundOutputs(address types.Address, offset, limit uint64) ([]SiafundOutput, error)
Expand Down Expand Up @@ -131,6 +132,11 @@ func (e *Explorer) MerkleProof(leafIndex uint64) ([]types.Hash256, error) {
return e.s.MerkleProof(leafIndex)
}

// Metrics returns various metrics about Sia.
func (e *Explorer) Metrics() (Metrics, error) {
return e.s.Metrics()
}

// Transactions returns the transactions with the specified IDs.
func (e *Explorer) Transactions(ids []types.TransactionID) ([]Transaction, error) {
return e.s.Transactions(ids)
Expand Down
16 changes: 16 additions & 0 deletions explorer/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"time"

"go.sia.tech/core/consensus"
"go.sia.tech/core/types"
)

Expand Down Expand Up @@ -104,7 +105,22 @@ type Block struct {

ParentID types.BlockID `json:"parentID"`
Nonce uint64 `json:"nonce"`
Difficulty consensus.Work `json:"difficulty"`
Timestamp time.Time `json:"timestamp"`
MinerPayouts []SiacoinOutput `json:"minerPayouts"`
Transactions []Transaction `json:"transactions"`
}

// Metrics contains various statistics relevant to the health of the Sia network.
type Metrics struct {
// Current chain height
Height uint64 `json:"height"`
// Current difficulty
Difficulty consensus.Work `json:"difficulty"`
// Total announced hosts
TotalHosts uint64 `json:"totalHosts"`
// Active contracts
ActiveContracts uint64 `json:"activeContracts"`
// Current storage utilization, in bytes
StorageUtilization uint64 `json:"storageUtilization"`
}
12 changes: 8 additions & 4 deletions explorer/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package explorer
import (
"fmt"

"go.sia.tech/core/consensus"
"go.sia.tech/core/types"
"go.sia.tech/coreutils/chain"
)
Expand Down Expand Up @@ -31,8 +32,9 @@ type (
// An UpdateState contains information relevant to the block being applied
// or reverted.
UpdateState struct {
Block types.Block
Index types.ChainIndex
Block types.Block
Difficulty consensus.Work
Index types.ChainIndex

Events []Event
TreeUpdates []TreeNodeUpdate
Expand Down Expand Up @@ -156,8 +158,9 @@ func applyChainUpdate(tx UpdateTx, cau chain.ApplyUpdate) error {

events := AppliedEvents(cau.State, cau.Block, cau)
state := UpdateState{
Block: cau.Block,
Index: cau.State.Index,
Block: cau.Block,
Difficulty: cau.State.Difficulty,
Index: cau.State.Index,

Events: events,
TreeUpdates: treeUpdates,
Expand Down Expand Up @@ -252,6 +255,7 @@ func revertChainUpdate(tx UpdateTx, cru chain.RevertUpdate, revertedIndex types.

state := UpdateState{
Block: cru.Block,
Difficulty: cru.State.Difficulty,
Index: revertedIndex,
TreeUpdates: treeUpdates,

Expand Down
2 changes: 1 addition & 1 deletion persist/sqlite/blocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
// Block implements explorer.Store.
func (s *Store) Block(id types.BlockID) (result explorer.Block, err error) {
err = s.transaction(func(tx *txn) error {
err = tx.QueryRow(`SELECT parent_id, nonce, timestamp, height FROM blocks WHERE id=?`, encode(id)).Scan(decode(&result.ParentID), decode(&result.Nonce), decode(&result.Timestamp), &result.Height)
err = tx.QueryRow(`SELECT parent_id, nonce, difficulty, timestamp, height FROM blocks WHERE id=?`, encode(id)).Scan(decode(&result.ParentID), decode(&result.Nonce), decode(&result.Difficulty), decode(&result.Timestamp), &result.Height)
if err != nil {
return err
}
Expand Down
8 changes: 5 additions & 3 deletions persist/sqlite/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"errors"
"fmt"

"go.sia.tech/core/consensus"
"go.sia.tech/core/types"
"go.sia.tech/coreutils/chain"
"go.sia.tech/explored/explorer"
Expand All @@ -16,9 +17,9 @@ type updateTx struct {
tx *txn
}

func addBlock(tx *txn, b types.Block, height uint64) error {
func addBlock(tx *txn, b types.Block, height uint64, difficulty consensus.Work) error {
// nonce is encoded because database/sql doesn't support uint64 with high bit set
_, err := tx.Exec("INSERT INTO blocks(id, height, parent_id, nonce, timestamp) VALUES (?, ?, ?, ?, ?);", encode(b.ID()), height, encode(b.ParentID), encode(b.Nonce), encode(b.Timestamp))
_, err := tx.Exec("INSERT INTO blocks(id, height, parent_id, nonce, difficulty, timestamp) VALUES (?, ?, ?, ?, ?, ?);", encode(b.ID()), height, encode(b.ParentID), encode(b.Nonce), encode(difficulty), encode(b.Timestamp))
return err
}

Expand Down Expand Up @@ -754,6 +755,7 @@ func addFileContractElements(tx *txn, b types.Block, fces []explorer.FileContrac
if err != nil {
return fmt.Errorf("failed to execute file_contract_elements statement: %w", err)
}
// log.Printf("%v (%d) - resolved: %v, valid: %v", fcID, fc.RevisionNumber, resolved, valid)
chris124567 marked this conversation as resolved.
Show resolved Hide resolved

// only update if it's the most recent revision which will come from
// running ForEachFileContractElement on the update
Expand Down Expand Up @@ -814,7 +816,7 @@ func addFileContractElements(tx *txn, b types.Block, fces []explorer.FileContrac
}

func (ut *updateTx) ApplyIndex(state explorer.UpdateState) error {
if err := addBlock(ut.tx, state.Block, state.Index.Height); err != nil {
if err := addBlock(ut.tx, state.Block, state.Index.Height, state.Difficulty); err != nil {
return fmt.Errorf("ApplyIndex: failed to add block: %w", err)
} else if err := updateMaturedBalances(ut.tx, false, state.Index.Height); err != nil {
return fmt.Errorf("ApplyIndex: failed to update matured balances: %w", err)
Expand Down
Loading
Loading