made logger init automatically

This commit is contained in:
Matt Johnstone 2024-10-27 15:20:48 +02:00
parent 43a02d763b
commit 36a11a9b23
No known key found for this signature in database
GPG Key ID: BE985FBB9BE7D3BB
4 changed files with 58 additions and 53 deletions

View File

@ -50,10 +50,6 @@ type SolanaCollector struct {
NodeFirstAvailableBlock *GaugeDesc NodeFirstAvailableBlock *GaugeDesc
} }
func init() {
slog.Init()
}
func NewSolanaCollector(provider rpc.Provider, config *ExporterConfig) *SolanaCollector { func NewSolanaCollector(provider rpc.Provider, config *ExporterConfig) *SolanaCollector {
collector := &SolanaCollector{ collector := &SolanaCollector{
rpcClient: provider, rpcClient: provider,

View File

@ -35,49 +35,57 @@ type (
// It provides methods to retrieve block production information, epoch info, slot info, vote accounts, and node version. // It provides methods to retrieve block production information, epoch info, slot info, vote accounts, and node version.
type Provider interface { type Provider interface {
// GetBlockProduction retrieves the block production information for the specified slot range. // GetBlockProduction returns recent block production information from the current or previous epoch.
// The method takes a context for cancellation, and pointers to the first and last slots of the range. // See API docs: https://solana.com/docs/rpc/http/getblockproduction
// It returns a BlockProduction struct containing the block production details, or an error if the operation fails.
GetBlockProduction( GetBlockProduction(
ctx context.Context, commitment Commitment, identity *string, firstSlot *int64, lastSlot *int64, ctx context.Context, commitment Commitment, identity *string, firstSlot *int64, lastSlot *int64,
) (*BlockProduction, error) ) (*BlockProduction, error)
// GetEpochInfo retrieves the information regarding the current epoch. // GetEpochInfo returns information about the current epoch.
// The method takes a context for cancellation and a commitment level to specify the desired state. // See API docs: https://solana.com/docs/rpc/http/getepochinfo
// It returns a pointer to an EpochInfo struct containing the epoch details, or an error if the operation fails.
GetEpochInfo(ctx context.Context, commitment Commitment) (*EpochInfo, error) GetEpochInfo(ctx context.Context, commitment Commitment) (*EpochInfo, error)
// GetSlot retrieves the current slot number. // GetSlot returns the slot that has reached the given or default commitment level.
// The method takes a context for cancellation. // See API docs: https://solana.com/docs/rpc/http/getslot
// It returns the current slot number as an int64, or an error if the operation fails.
GetSlot(ctx context.Context, commitment Commitment) (int64, error) GetSlot(ctx context.Context, commitment Commitment) (int64, error)
// GetVoteAccounts retrieves the vote accounts information. // GetVoteAccounts returns the account info and associated stake for all the voting accounts in the current bank.
// The method takes a context for cancellation and a slice of parameters to filter the vote accounts. // See API docs: https://solana.com/docs/rpc/http/getvoteaccounts
// It returns a pointer to a VoteAccounts struct containing the vote accounts details,
// or an error if the operation fails.
GetVoteAccounts(ctx context.Context, commitment Commitment, votePubkey *string) (*VoteAccounts, error) GetVoteAccounts(ctx context.Context, commitment Commitment, votePubkey *string) (*VoteAccounts, error)
// GetVersion retrieves the version of the Solana node. // GetVersion returns the current Solana version running on the node.
// The method takes a context for cancellation. // See API docs: https://solana.com/docs/rpc/http/getversion
// It returns a string containing the version information, or an error if the operation fails.
GetVersion(ctx context.Context) (string, error) GetVersion(ctx context.Context) (string, error)
// GetBalance returns the SOL balance of the account at the provided address // GetBalance returns the lamport balance of the account of provided pubkey.
// See API docs:https://solana.com/docs/rpc/http/getbalance
GetBalance(ctx context.Context, commitment Commitment, address string) (float64, error) GetBalance(ctx context.Context, commitment Commitment, address string) (float64, error)
// GetInflationReward returns the inflation rewards (in lamports) awarded to the given addresses (vote accounts) // GetInflationReward returns the inflation / staking reward for a list of addresses for an epoch.
// during the given epoch. // See API docs: https://solana.com/docs/rpc/http/getinflationreward
GetInflationReward( GetInflationReward(
ctx context.Context, commitment Commitment, addresses []string, epoch *int64, minContextSlot *int64, ctx context.Context, commitment Commitment, addresses []string, epoch *int64, minContextSlot *int64,
) ([]InflationReward, error) ) ([]InflationReward, error)
// GetLeaderSchedule returns the leader schedule for an epoch.
// See API docs: https://solana.com/docs/rpc/http/getleaderschedule
GetLeaderSchedule(ctx context.Context, commitment Commitment, slot int64) (map[string][]int64, error) GetLeaderSchedule(ctx context.Context, commitment Commitment, slot int64) (map[string][]int64, error)
// GetBlock returns identity and transaction information about a confirmed block in the ledger.
// See API docs: https://solana.com/docs/rpc/http/getblock
GetBlock(ctx context.Context, commitment Commitment, slot int64, transactionDetails string) (*Block, error) GetBlock(ctx context.Context, commitment Commitment, slot int64, transactionDetails string) (*Block, error)
// GetHealth returns the current health of the node. A healthy node is one that is within a blockchain-configured slots
// of the latest cluster confirmed slot.
// See API docs: https://solana.com/docs/rpc/http/gethealth
GetHealth(ctx context.Context) (*string, error) GetHealth(ctx context.Context) (*string, error)
// GetMinimumLedgerSlot returns the lowest slot that the node has information about in its ledger.
// See API docs: https://solana.com/docs/rpc/http/minimumledgerslot
GetMinimumLedgerSlot(ctx context.Context) (*int64, error) GetMinimumLedgerSlot(ctx context.Context) (*int64, error)
// GetFirstAvailableBlock returns the slot of the lowest confirmed block that has not been purged from the ledger
// See API docs: https://solana.com/docs/rpc/http/getfirstavailableblock
GetFirstAvailableBlock(ctx context.Context) (*int64, error) GetFirstAvailableBlock(ctx context.Context) (*int64, error)
} }

View File

@ -15,11 +15,11 @@ import (
type ( type (
// MockServer represents a mock Solana RPC server for testing // MockServer represents a mock Solana RPC server for testing
MockServer struct { MockServer struct {
server *http.Server // Responses allows tests to set custom responses for specific methods
listener net.Listener Responses map[string]any
// ResponseMap allows tests to set custom responses for specific methods server *http.Server
ResponseMap map[string]any listener net.Listener
mu sync.RWMutex mu sync.RWMutex
} }
// RPCResponse represents a JSON-RPC response // RPCResponse represents a JSON-RPC response
@ -32,13 +32,13 @@ type (
) )
// NewMockServer creates a new mock server instance // NewMockServer creates a new mock server instance
func NewMockServer() (*MockServer, error) { func NewMockServer(responses map[string]any) (*MockServer, error) {
listener, err := net.Listen("tcp", "127.0.0.1:0") listener, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to create listener: %v", err) return nil, fmt.Errorf("failed to create listener: %v", err)
} }
ms := &MockServer{listener: listener, ResponseMap: make(map[string]any)} ms := &MockServer{listener: listener, Responses: responses}
mux := http.NewServeMux() mux := http.NewServeMux()
mux.HandleFunc("/", ms.handleRPCRequest) mux.HandleFunc("/", ms.handleRPCRequest)
@ -64,11 +64,17 @@ func (ms *MockServer) Close() error {
return ms.server.Shutdown(ctx) return ms.server.Shutdown(ctx)
} }
func (ms *MockServer) MustClose() {
if err := ms.Close(); err != nil {
panic(err)
}
}
// SetResponse sets a custom response for a specific method // SetResponse sets a custom response for a specific method
func (ms *MockServer) SetResponse(method string, response any) { func (ms *MockServer) SetResponse(method string, response any) {
ms.mu.Lock() ms.mu.Lock()
defer ms.mu.Unlock() defer ms.mu.Unlock()
ms.ResponseMap[method] = response ms.Responses[method] = response
} }
func (ms *MockServer) handleRPCRequest(w http.ResponseWriter, r *http.Request) { func (ms *MockServer) handleRPCRequest(w http.ResponseWriter, r *http.Request) {
@ -83,43 +89,38 @@ func (ms *MockServer) handleRPCRequest(w http.ResponseWriter, r *http.Request) {
return return
} }
response := RPCResponse{JsonRPC: "2.0", ID: req.Id}
ms.mu.RLock() ms.mu.RLock()
result, exists := ms.ResponseMap[req.Method] result, exists := ms.Responses[req.Method]
ms.mu.RUnlock() ms.mu.RUnlock()
if !exists { if !exists {
// Fall back to default responses if no custom response is set // Fall back to default responses if no custom response is set
result = getDefaultResponse(req.Method) response.Error = rpc.RPCError{
Code: -32601,
Message: "Method not found",
}
} else {
response.Result = result
} }
response := RPCResponse{JsonRPC: "2.0", Result: result, ID: req.Id}
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(response) err := json.NewEncoder(w).Encode(response)
} if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
// Helper function to get default responses
func getDefaultResponse(method string) any {
switch method {
case "getBalance":
return map[string]any{"context": map[string]any{"slot": 1234567}, "value": 100000000}
case "getSlot":
return 1234567
// Add more default responses as needed
default:
return nil
} }
} }
// TestHelper is a helper struct for tests // TestHelper is a helper struct for tests
type TestHelper struct { type TestHelper struct {
Server *MockServer Server *MockServer
Client *rpc.Client
T *testing.T T *testing.T
} }
// NewTestHelper creates a new test helper with a running mock server // NewTestHelper creates a new test helper with a running mock server
func NewTestHelper(t *testing.T) *TestHelper { func NewTestHelper(t *testing.T, responses map[string]any) *TestHelper {
server, err := NewMockServer() server, err := NewMockServer(responses)
if err != nil { if err != nil {
t.Fatalf("Failed to create mock server: %v", err) t.Fatalf("Failed to create mock server: %v", err)
} }
@ -130,5 +131,5 @@ func NewTestHelper(t *testing.T) *TestHelper {
} }
}) })
return &TestHelper{Server: server, T: t} return &TestHelper{Server: server, Client: rpc.NewRPCClient(server.URL(), time.Second), T: t}
} }

View File

@ -10,8 +10,8 @@ import (
var log *zap.SugaredLogger var log *zap.SugaredLogger
// Init initializes the logger // init initializes the logger
func Init() { func init() {
config := zap.NewProductionConfig() config := zap.NewProductionConfig()
// configure: // configure: