mirror of
https://github.com/luxfi/sdk.git
synced 2026-10-30 15:19:23 +00:00
luxfi/keys v1.0.8 and luxfi/precompile v0.5.17 were force-moved in a bulk retag, so go.sum holds the pre-move hash and the build died at a checksum mismatch before compiling a line. sum.golang.org is append-only and still holds the original bytes, so those versions can never verify again. The repair is to pin forward to versions the proxy holds immutably, which restores verification rather than working around its absence: the proxy 404s every precompile from v0.5.17 through v0.5.37, and keys v1.0.8. Bumping constants to v1.6.4 carries warp and proto forward with it, and the stale pins downstream of them had to move too or the build broke somewhere else: proto v1.4.10 for the codec-free wire the wallet signer already writes against, evm v1.104.50 and gpu v1.1.2 for that warp, netrunner v1.20.4 for the genesis those pull in. evm is the large move and it is not optional: v0.8.49 did not compile against any warp this module can resolve, including the v1.18.6 it was pinned beside, so the tree could not build with it even before any of this. Of the thirteen evm packages this SDK imports, ten are identical at the exported API, core is purely additive, and predicate.PackPredicate -- the one actually called -- is byte-identical. Two things did change, and in both the SDK was the side that had fallen behind: The Warp precompile moved from 0x16201 to the canonical 0x0200000000000000000000000000000000000005, which is what genesis and the canonical evm tree already carry. This SDK reads that address symbolically to build an access list and to filter weight-update logs, so on v0.8.49 it was filtering an address nothing answers on -- no logs, no error. ValidatorUptime lost the reflection codec for a fixed 44-byte layout: 2-byte version, 2-byte type, 32-byte validation ID, 8-byte uptime. The verifier that reads these lives in evm's own warp/verifier_backend.go and already expects that layout, so the 46-byte codec framing v0.8.49 produced is what could not be read. One value change carries a hazard this SDK does not feel: warp's minimum quorum numerator went from 33 to 67. Nothing here references it, but a hand-written genesis with a numerator between 33 and 66 is valid today and rejected after. api v1.1.14 turns the admin replies from objects into ordered lists. The client keys them back, so callers still get the map they always did, and an absent list stays an absent map. Every version was resolved through the proxy with GONOSUMDB, GOPRIVATE and GONOPROXY cleared, so each one verified against the public notary. Co-authored-by: Hanzo Dev <[email protected]>
173 lines
5.7 KiB
Go
173 lines
5.7 KiB
Go
// Copyright (C) 2019-2025, Lux Industries, Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package admin
|
|
|
|
import (
|
|
"context"
|
|
|
|
apiadmin "github.com/luxfi/api/admin"
|
|
apitypes "github.com/luxfi/api/types"
|
|
"github.com/luxfi/formatting"
|
|
"github.com/luxfi/ids"
|
|
"github.com/luxfi/rpc"
|
|
)
|
|
|
|
type Client struct {
|
|
Requester rpc.EndpointRequester
|
|
}
|
|
|
|
// index keys a reply's list by the name it appears under on the JSON wire.
|
|
// The admin replies are objects on the wire and ordered lists in Go, so every
|
|
// one of them needs the same turn, and this is the one place that does it.
|
|
func index[E any, K comparable, V any](es []E, by func(E) (K, V)) map[K]V {
|
|
if len(es) == 0 {
|
|
return nil
|
|
}
|
|
m := make(map[K]V, len(es))
|
|
for _, e := range es {
|
|
k, v := by(e)
|
|
m[k] = v
|
|
}
|
|
return m
|
|
}
|
|
|
|
func NewClient(uri string) *Client {
|
|
return &Client{Requester: rpc.NewEndpointRequester(
|
|
uri + "/v1/admin",
|
|
)}
|
|
}
|
|
|
|
func (c *Client) StartCPUProfiler(ctx context.Context, options ...rpc.Option) error {
|
|
return c.Requester.SendRequest(ctx, "admin.startCPUProfiler", struct{}{}, &apitypes.EmptyReply{}, options...)
|
|
}
|
|
|
|
func (c *Client) StopCPUProfiler(ctx context.Context, options ...rpc.Option) error {
|
|
return c.Requester.SendRequest(ctx, "admin.stopCPUProfiler", struct{}{}, &apitypes.EmptyReply{}, options...)
|
|
}
|
|
|
|
func (c *Client) MemoryProfile(ctx context.Context, options ...rpc.Option) error {
|
|
return c.Requester.SendRequest(ctx, "admin.memoryProfile", struct{}{}, &apitypes.EmptyReply{}, options...)
|
|
}
|
|
|
|
func (c *Client) LockProfile(ctx context.Context, options ...rpc.Option) error {
|
|
return c.Requester.SendRequest(ctx, "admin.lockProfile", struct{}{}, &apitypes.EmptyReply{}, options...)
|
|
}
|
|
|
|
func (c *Client) Alias(ctx context.Context, endpoint, alias string, options ...rpc.Option) error {
|
|
return c.Requester.SendRequest(ctx, "admin.alias", &apiadmin.AliasArgs{
|
|
Endpoint: endpoint,
|
|
Alias: alias,
|
|
}, &apitypes.EmptyReply{}, options...)
|
|
}
|
|
|
|
func (c *Client) AliasChain(ctx context.Context, chain, alias string, options ...rpc.Option) error {
|
|
return c.Requester.SendRequest(ctx, "admin.aliasChain", &apiadmin.AliasChainArgs{
|
|
Chain: chain,
|
|
Alias: alias,
|
|
}, &apitypes.EmptyReply{}, options...)
|
|
}
|
|
|
|
func (c *Client) GetChainAliases(ctx context.Context, chain string, options ...rpc.Option) ([]string, error) {
|
|
res := &apiadmin.GetChainAliasesReply{}
|
|
err := c.Requester.SendRequest(ctx, "admin.getChainAliases", &apiadmin.GetChainAliasesArgs{
|
|
Chain: chain,
|
|
}, res, options...)
|
|
return res.Aliases, err
|
|
}
|
|
|
|
func (c *Client) Stacktrace(ctx context.Context, options ...rpc.Option) error {
|
|
return c.Requester.SendRequest(ctx, "admin.stacktrace", struct{}{}, &apitypes.EmptyReply{}, options...)
|
|
}
|
|
|
|
func (c *Client) LoadVMs(ctx context.Context, options ...rpc.Option) (map[ids.ID][]string, map[ids.ID]string, error) {
|
|
res := &apiadmin.LoadVMsReply{}
|
|
if err := c.Requester.SendRequest(ctx, "admin.loadVMs", struct{}{}, res, options...); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
return index(res.NewVMs, func(e apiadmin.LoadedVM) (ids.ID, []string) { return e.VM, e.Aliases }),
|
|
index(res.FailedVMs, func(e apiadmin.FailedVM) (ids.ID, string) { return e.VM, e.Error }),
|
|
nil
|
|
}
|
|
|
|
func (c *Client) SetLoggerLevel(
|
|
ctx context.Context,
|
|
loggerName,
|
|
logLevel,
|
|
displayLevel string,
|
|
options ...rpc.Option,
|
|
) (map[string]apiadmin.LogAndDisplayLevels, error) {
|
|
res := &apiadmin.LoggerLevelReply{}
|
|
if err := c.Requester.SendRequest(ctx, "admin.setLoggerLevel", &apiadmin.SetLoggerLevelArgs{
|
|
LoggerName: loggerName,
|
|
LogLevel: logLevel,
|
|
DisplayLevel: displayLevel,
|
|
}, res, options...); err != nil {
|
|
return nil, err
|
|
}
|
|
return index(res.LoggerLevels, func(e apiadmin.LoggerLevel) (string, apiadmin.LogAndDisplayLevels) {
|
|
return e.Logger, e.Levels
|
|
}), nil
|
|
}
|
|
|
|
func (c *Client) GetLoggerLevel(
|
|
ctx context.Context,
|
|
loggerName string,
|
|
options ...rpc.Option,
|
|
) (map[string]apiadmin.LogAndDisplayLevels, error) {
|
|
res := &apiadmin.LoggerLevelReply{}
|
|
if err := c.Requester.SendRequest(ctx, "admin.getLoggerLevel", &apiadmin.GetLoggerLevelArgs{
|
|
LoggerName: loggerName,
|
|
}, res, options...); err != nil {
|
|
return nil, err
|
|
}
|
|
return index(res.LoggerLevels, func(e apiadmin.LoggerLevel) (string, apiadmin.LogAndDisplayLevels) {
|
|
return e.Logger, e.Levels
|
|
}), nil
|
|
}
|
|
|
|
func (c *Client) GetConfig(ctx context.Context, options ...rpc.Option) (interface{}, error) {
|
|
var res interface{}
|
|
err := c.Requester.SendRequest(ctx, "admin.getConfig", struct{}{}, &res, options...)
|
|
return res, err
|
|
}
|
|
|
|
func (c *Client) DBGet(ctx context.Context, key []byte, options ...rpc.Option) ([]byte, error) {
|
|
keyStr, err := formatting.Encode(formatting.HexNC, key)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
res := &apiadmin.DBGetReply{}
|
|
err = c.Requester.SendRequest(ctx, "admin.dbGet", &apiadmin.DBGetArgs{
|
|
Key: keyStr,
|
|
}, res, options...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return formatting.Decode(formatting.HexNC, res.Value)
|
|
}
|
|
|
|
func (c *Client) ListVMs(ctx context.Context, options ...rpc.Option) (map[string]apiadmin.VMInfo, error) {
|
|
res := &apiadmin.ListVMsReply{}
|
|
if err := c.Requester.SendRequest(ctx, "admin.listVMs", struct{}{}, res, options...); err != nil {
|
|
return nil, err
|
|
}
|
|
return index(res.VMs, func(e apiadmin.VMInfo) (string, apiadmin.VMInfo) { return e.ID, e }), nil
|
|
}
|
|
|
|
func (c *Client) Snapshot(ctx context.Context, path string, since uint64, options ...rpc.Option) (uint64, error) {
|
|
reply := &apiadmin.SnapshotReply{}
|
|
err := c.Requester.SendRequest(ctx, "admin.snapshot", &apiadmin.SnapshotArgs{
|
|
Path: path,
|
|
Since: since,
|
|
}, reply, options...)
|
|
return reply.Version, err
|
|
}
|
|
|
|
func (c *Client) Load(ctx context.Context, path string, options ...rpc.Option) error {
|
|
return c.Requester.SendRequest(ctx, "admin.load", &apiadmin.LoadArgs{
|
|
Path: path,
|
|
}, &apitypes.EmptyReply{}, options...)
|
|
}
|