feat(rpc): GetInfo, GetHeight, GetBlockCount endpoints
Co-Authored-By: Charon <charon@lethean.io> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
03c11b3bbd
commit
efbace75a8
2 changed files with 158 additions and 0 deletions
58
rpc/info.go
Normal file
58
rpc/info.go
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
// Copyright (c) 2017-2026 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
package rpc
|
||||
|
||||
import "fmt"
|
||||
|
||||
// GetInfo returns the daemon status.
|
||||
// Uses flags=0 for the cheapest query (no expensive calculations).
|
||||
func (c *Client) GetInfo() (*DaemonInfo, error) {
|
||||
params := struct {
|
||||
Flags uint64 `json:"flags"`
|
||||
}{Flags: 0}
|
||||
var resp struct {
|
||||
DaemonInfo
|
||||
Status string `json:"status"`
|
||||
}
|
||||
if err := c.call("getinfo", params, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.Status != "OK" {
|
||||
return nil, fmt.Errorf("getinfo: status %q", resp.Status)
|
||||
}
|
||||
return &resp.DaemonInfo, nil
|
||||
}
|
||||
|
||||
// GetHeight returns the current blockchain height.
|
||||
// Uses the legacy /getheight endpoint (not available via /json_rpc).
|
||||
func (c *Client) GetHeight() (uint64, error) {
|
||||
var resp struct {
|
||||
Height uint64 `json:"height"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
if err := c.legacyCall("/getheight", struct{}{}, &resp); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if resp.Status != "OK" {
|
||||
return 0, fmt.Errorf("getheight: status %q", resp.Status)
|
||||
}
|
||||
return resp.Height, nil
|
||||
}
|
||||
|
||||
// GetBlockCount returns the total number of blocks (height of top block + 1).
|
||||
func (c *Client) GetBlockCount() (uint64, error) {
|
||||
var resp struct {
|
||||
Count uint64 `json:"count"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
if err := c.call("getblockcount", struct{}{}, &resp); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if resp.Status != "OK" {
|
||||
return 0, fmt.Errorf("getblockcount: status %q", resp.Status)
|
||||
}
|
||||
return resp.Count, nil
|
||||
}
|
||||
100
rpc/info_test.go
Normal file
100
rpc/info_test.go
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
// Copyright (c) 2017-2026 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetInfo_Good(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(jsonRPCResponse{
|
||||
JSONRPC: "2.0",
|
||||
ID: json.RawMessage(`"0"`),
|
||||
Result: json.RawMessage(`{
|
||||
"height": 6300,
|
||||
"tx_count": 12345,
|
||||
"tx_pool_size": 3,
|
||||
"outgoing_connections_count": 8,
|
||||
"incoming_connections_count": 4,
|
||||
"synchronized_connections_count": 7,
|
||||
"daemon_network_state": 2,
|
||||
"pow_difficulty": 1000000,
|
||||
"block_reward": 1000000000000,
|
||||
"default_fee": 10000000000,
|
||||
"minimum_fee": 10000000000,
|
||||
"last_block_hash": "abc123",
|
||||
"total_coins": "17500000000000000000",
|
||||
"pos_allowed": true,
|
||||
"status": "OK"
|
||||
}`),
|
||||
})
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
c := NewClient(srv.URL)
|
||||
info, err := c.GetInfo()
|
||||
if err != nil {
|
||||
t.Fatalf("GetInfo: %v", err)
|
||||
}
|
||||
if info.Height != 6300 {
|
||||
t.Errorf("height: got %d, want 6300", info.Height)
|
||||
}
|
||||
if info.TxCount != 12345 {
|
||||
t.Errorf("tx_count: got %d, want 12345", info.TxCount)
|
||||
}
|
||||
if info.BlockReward != 1000000000000 {
|
||||
t.Errorf("block_reward: got %d, want 1000000000000", info.BlockReward)
|
||||
}
|
||||
if !info.PosAllowed {
|
||||
t.Error("pos_allowed: got false, want true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetHeight_Good(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path != "/getheight" {
|
||||
t.Errorf("path: got %s, want /getheight", r.URL.Path)
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write([]byte(`{"height":6300,"status":"OK"}`))
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
c := NewClient(srv.URL)
|
||||
height, err := c.GetHeight()
|
||||
if err != nil {
|
||||
t.Fatalf("GetHeight: %v", err)
|
||||
}
|
||||
if height != 6300 {
|
||||
t.Errorf("height: got %d, want 6300", height)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetBlockCount_Good(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(jsonRPCResponse{
|
||||
JSONRPC: "2.0",
|
||||
ID: json.RawMessage(`"0"`),
|
||||
Result: json.RawMessage(`{"count":6301,"status":"OK"}`),
|
||||
})
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
c := NewClient(srv.URL)
|
||||
count, err := c.GetBlockCount()
|
||||
if err != nil {
|
||||
t.Fatalf("GetBlockCount: %v", err)
|
||||
}
|
||||
if count != 6301 {
|
||||
t.Errorf("count: got %d, want 6301", count)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue