Remove Kafka, Clickhouse-related tools
To be readded when we find a maintainer. #frühjahrsputz
This commit is contained in:
parent
8f27f10358
commit
382e723242
|
@ -1,261 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gagliardetto/solana-go/rpc/ws"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/twmb/franz-go/pkg/kgo"
|
||||
"go.firedancer.io/radiance/pkg/envfile"
|
||||
"go.firedancer.io/radiance/pkg/kafka"
|
||||
"go.firedancer.io/radiance/pkg/leaderschedule"
|
||||
envv1 "go.firedancer.io/radiance/proto/env/v1"
|
||||
networkv1 "go.firedancer.io/radiance/proto/network/v1"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
flagEnv = flag.String("env", ".env.prototxt", "Env file (.prototxt)")
|
||||
flagOnly = flag.String("only", "", "Only watch specified nodes (comma-separated)")
|
||||
|
||||
flagType = flag.String("type", "", "Only print specific types to log")
|
||||
|
||||
flagKafka = flag.Bool("kafka", false, "Enable Kafka publishing")
|
||||
flagKafkaTopic = flag.String("kafkaTopic", "slot_status", "Kafka topic suffix to publish to")
|
||||
|
||||
flagDebugAddr = flag.String("debugAddr", "localhost:6060", "pprof/metrics listen address")
|
||||
)
|
||||
|
||||
func init() {
|
||||
klog.InitFlags(nil)
|
||||
flag.Parse()
|
||||
}
|
||||
|
||||
/*
|
||||
I0612 20:37:10.076826 916547 slot.go:111] val1.ffm1: slot=137326466 type=firstShredReceived delta=7ms parent=0
|
||||
I0612 20:37:10.428919 916547 slot.go:111] val1.ffm1: slot=137326466 type=completed delta=7ms parent=0
|
||||
I0612 20:37:10.687256 916547 slot.go:111] val1.ffm1: slot=137326466 type=createdBank delta=4ms parent=137326465
|
||||
I0612 20:37:10.691104 916547 slot.go:136] val1.ffm1: slot=137326466 root=137326431 parent=137326465
|
||||
I0612 20:37:11.232413 916547 slot.go:111] val1.ffm1: slot=137326466 type=frozen delta=8ms parent=0
|
||||
I0612 20:37:12.480333 916547 slot.go:111] val1.ffm1: slot=137326466 type=optimisticConfirmation delta=8ms parent=0
|
||||
I0612 20:37:43.279139 916547 slot.go:111] val1.ffm1: slot=137326466 type=root delta=9ms parent=0
|
||||
I0612 20:37:43.805364 916547 slot.go:111] val1.ffm1: slot=137326466 type=root delta=8ms parent=0
|
||||
*/
|
||||
|
||||
func main() {
|
||||
env, err := envfile.Load(*flagEnv)
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed to load env file: %v", err)
|
||||
}
|
||||
|
||||
nodes := env.GetNodes()
|
||||
if len(nodes) == 0 {
|
||||
klog.Fatalf("No nodes found in env file")
|
||||
}
|
||||
|
||||
go func() {
|
||||
klog.Error(http.ListenAndServe(*flagDebugAddr, nil))
|
||||
}()
|
||||
|
||||
nodes = envfile.FilterNodes(nodes, envfile.ParseOnlyFlag(*flagOnly))
|
||||
|
||||
if len(nodes) == 0 {
|
||||
klog.Exitf("No nodes in environment or all nodes filtered")
|
||||
}
|
||||
klog.Infof("Watching %d nodes", len(nodes))
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
highest := &sync.Map{}
|
||||
|
||||
sched := &leaderschedule.Tracker{}
|
||||
|
||||
go sched.Run(ctx, env.Nodes)
|
||||
|
||||
var kcl *kgo.Client
|
||||
var topic string
|
||||
if *flagKafka {
|
||||
if *flagKafkaTopic == "" {
|
||||
klog.Exitf("Kafka enabled but no topic specified")
|
||||
}
|
||||
topic = strings.Join([]string{env.Kafka.TopicPrefix, *flagKafkaTopic}, ".")
|
||||
klog.Infof("Publishing to topic %s", topic)
|
||||
kcl, err = kafka.NewClientFromEnv(env.Kafka)
|
||||
if err != nil {
|
||||
klog.Exitf("Failed to create kafka client: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, node := range nodes {
|
||||
node := node
|
||||
go func() {
|
||||
for {
|
||||
if err := watchSlotUpdates(ctx, node, highest, sched, kcl, topic); err != nil {
|
||||
klog.Errorf("watchSlotUpdates on node %s, reconnecting: %v", node.Name, err)
|
||||
}
|
||||
time.Sleep(time.Second * 5)
|
||||
}
|
||||
}()
|
||||
|
||||
if *flagType == "" {
|
||||
go func() {
|
||||
for {
|
||||
if err := watchSlots(ctx, node); err != nil {
|
||||
klog.Errorf("watchSlots on node %s, reconnecting: %v", node.Name, err)
|
||||
}
|
||||
time.Sleep(time.Second * 5)
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
select {}
|
||||
}
|
||||
|
||||
func watchSlotUpdates(ctx context.Context, node *envv1.RPCNode, highest *sync.Map, sched *leaderschedule.Tracker, kcl *kgo.Client, topic string) error {
|
||||
timeout, cancel := context.WithTimeout(ctx, time.Second*10)
|
||||
defer cancel()
|
||||
|
||||
c, err := ws.Connect(timeout, node.Ws)
|
||||
if err != nil {
|
||||
return fmt.Errorf("connect: %w", err)
|
||||
}
|
||||
|
||||
sub, err := c.SlotsUpdatesSubscribe()
|
||||
if err != nil {
|
||||
return fmt.Errorf("subscribe: %w", err)
|
||||
}
|
||||
|
||||
for {
|
||||
m, err := sub.Recv()
|
||||
if err != nil {
|
||||
return fmt.Errorf("recv: %w", err)
|
||||
}
|
||||
|
||||
ts := m.Timestamp.Time()
|
||||
delay := time.Since(ts)
|
||||
|
||||
sched.Update(m.Slot)
|
||||
|
||||
var first time.Time
|
||||
if m.Type == ws.SlotsUpdatesFirstShredReceived {
|
||||
value, _ := highest.LoadOrStore(m.Slot, ts)
|
||||
first = value.(time.Time)
|
||||
} else {
|
||||
value, ok := highest.Load(m.Slot)
|
||||
if ok {
|
||||
first = value.(time.Time)
|
||||
}
|
||||
}
|
||||
|
||||
if m.Type == ws.SlotsUpdatesRoot {
|
||||
highest.Delete(m.Slot)
|
||||
}
|
||||
|
||||
var prop int64
|
||||
if !first.IsZero() {
|
||||
prop = ts.Sub(first).Milliseconds()
|
||||
} else {
|
||||
prop = -1
|
||||
}
|
||||
|
||||
if *flagType != "" && string(m.Type) != *flagType {
|
||||
continue
|
||||
}
|
||||
|
||||
leader := sched.Get(m.Slot)
|
||||
|
||||
if kcl != nil {
|
||||
var stats *networkv1.TxStats
|
||||
if m.Type == ws.SlotsUpdatesFrozen {
|
||||
stats = &networkv1.TxStats{
|
||||
NumTransactionEntries: m.Stats.NumTransactionEntries,
|
||||
NumSuccessfulTransactions: m.Stats.NumSuccessfulTransactions,
|
||||
NumFailedTransactions: m.Stats.NumFailedTransactions,
|
||||
MaxTransactionsPerEntry: m.Stats.MaxTransactionsPerEntry,
|
||||
}
|
||||
}
|
||||
|
||||
st := &networkv1.SlotStatus{
|
||||
Slot: m.Slot,
|
||||
Timestamp: uint64(ts.UnixMilli()),
|
||||
Delay: uint64(delay.Milliseconds()),
|
||||
Type: convertUpdateType(m.Type),
|
||||
Parent: m.Parent,
|
||||
Stats: stats,
|
||||
Err: "", // TODO
|
||||
Leader: leader.String(),
|
||||
Source: node.Name,
|
||||
}
|
||||
|
||||
// Fixed-length proto encoding
|
||||
buf := proto.NewBuffer([]byte{})
|
||||
if err := buf.EncodeMessage(st); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
r := &kgo.Record{Topic: topic, Value: buf.Bytes()}
|
||||
kcl.Produce(ctx, r, func(_ *kgo.Record, err error) {
|
||||
if err != nil {
|
||||
klog.Warningf("failed to publish message to %s: %v", topic, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
klog.V(1).Infof("%s: slot=%d type=%s delay=%dms prop=%dms parent=%d stats=%v leader=%s",
|
||||
node.Name, m.Slot, m.Type, delay.Milliseconds(), prop, m.Parent, m.Stats, leader)
|
||||
}
|
||||
}
|
||||
|
||||
func convertUpdateType(t ws.SlotsUpdatesType) networkv1.SlotStatus_UpdateType {
|
||||
switch t {
|
||||
case ws.SlotsUpdatesFirstShredReceived:
|
||||
return networkv1.SlotStatus_UPDATE_TYPE_FIRST_SHRED_RECEIVED
|
||||
case ws.SlotsUpdatesCompleted:
|
||||
return networkv1.SlotStatus_UPDATE_TYPE_COMPLETED
|
||||
case ws.SlotsUpdatesCreatedBank:
|
||||
return networkv1.SlotStatus_UPDATE_TYPE_CREATED_BANK
|
||||
case ws.SlotsUpdatesFrozen:
|
||||
return networkv1.SlotStatus_UPDATE_TYPE_FROZEN
|
||||
case ws.SlotsUpdatesDead:
|
||||
return networkv1.SlotStatus_UPDATE_TYPE_DEAD
|
||||
case ws.SlotsUpdatesOptimisticConfirmation:
|
||||
return networkv1.SlotStatus_UPDATE_TYPE_OPTIMISTIC_CONFIRMATION
|
||||
case ws.SlotsUpdatesRoot:
|
||||
return networkv1.SlotStatus_UPDATE_TYPE_ROOT
|
||||
default:
|
||||
panic("unknown slot update type " + t)
|
||||
}
|
||||
}
|
||||
|
||||
func watchSlots(ctx context.Context, node *envv1.RPCNode) error {
|
||||
timeout, cancel := context.WithTimeout(ctx, time.Second*10)
|
||||
defer cancel()
|
||||
|
||||
c, err := ws.Connect(timeout, node.Ws)
|
||||
if err != nil {
|
||||
return fmt.Errorf("connect: %w", err)
|
||||
}
|
||||
|
||||
sub, err := c.SlotSubscribe()
|
||||
if err != nil {
|
||||
return fmt.Errorf("subscribe: %w", err)
|
||||
}
|
||||
|
||||
for {
|
||||
m, err := sub.Recv()
|
||||
if err != nil {
|
||||
return fmt.Errorf("recv: %w", err)
|
||||
}
|
||||
|
||||
klog.V(1).Infof("%s: slot=%d root=%d parent=%d",
|
||||
node.Name, m.Slot, m.Root, m.Parent)
|
||||
}
|
||||
}
|
|
@ -1,143 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gagliardetto/solana-go"
|
||||
"github.com/gagliardetto/solana-go/rpc"
|
||||
"github.com/gagliardetto/solana-go/rpc/jsonrpc"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
const localRPC = "http://localhost:8899"
|
||||
|
||||
var (
|
||||
flagAddr = flag.String("addr", localRPC, "RPC address")
|
||||
flagCount = flag.Bool("count", true, "Print the number of transactions")
|
||||
flagAfter = flag.Uint64("after", 0, "Only print transactions after this slot")
|
||||
voteAcc = flag.String("voteAcc", "Certusm1sa411sMpV9FPqU5dXAYhmmhygvxJ23S6hJ24", "Vote account address")
|
||||
workers = flag.Uint("workers", 10, "Worker threads")
|
||||
)
|
||||
|
||||
type logLine struct {
|
||||
TS time.Time
|
||||
Slot uint64
|
||||
NumTx int
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
r := rpc.New(*flagAddr)
|
||||
|
||||
our, err := solana.PublicKeyFromBase58(*voteAcc)
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed to parse vote account: %v", err)
|
||||
}
|
||||
|
||||
klog.Infof("Our vote account: %v", our)
|
||||
|
||||
epr, err := r.GetEpochInfo(context.Background(), rpc.CommitmentConfirmed)
|
||||
if err != nil {
|
||||
klog.Exitf("GetEpochSchedule: %v", err)
|
||||
}
|
||||
|
||||
if epr == nil {
|
||||
klog.Exitf("GetEpochInfo: empty response")
|
||||
}
|
||||
|
||||
epoch := *epr
|
||||
offset := epoch.AbsoluteSlot - epoch.SlotIndex
|
||||
klog.Infof("Epoch: %v, SlotIndex: %v, AbsoluteSlot: %v, Offset: %v", epoch.Epoch, epoch.SlotIndex, epoch.AbsoluteSlot, offset)
|
||||
|
||||
resp, err := r.GetLeaderScheduleWithOpts(context.Background(), &rpc.GetLeaderScheduleOpts{
|
||||
Epoch: &epoch.AbsoluteSlot,
|
||||
Identity: &our,
|
||||
})
|
||||
if err != nil {
|
||||
klog.Exitf("GetLeaderSchedule: %v", err)
|
||||
}
|
||||
|
||||
if resp == nil {
|
||||
klog.Exitf("GetLeaderSchedule: empty response")
|
||||
}
|
||||
|
||||
current, err := r.GetSlot(context.Background(), rpc.CommitmentConfirmed)
|
||||
if err != nil {
|
||||
klog.Exitf("GetSlot: %v", err)
|
||||
}
|
||||
|
||||
klog.Infof("Current slot: %d", current)
|
||||
|
||||
sched := resp
|
||||
slots := sched[our]
|
||||
|
||||
klog.Infof("%d slots for %s", len(slots), our)
|
||||
|
||||
work := make(chan uint64)
|
||||
wg := sync.WaitGroup{}
|
||||
out := sync.Mutex{}
|
||||
|
||||
for i := 0; uint(i) < *workers; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
for {
|
||||
slot := <-work
|
||||
if slot == 0 {
|
||||
wg.Done()
|
||||
return
|
||||
}
|
||||
if *flagCount {
|
||||
block, err := r.GetBlock(context.Background(), slot)
|
||||
if err != nil {
|
||||
var rpcErr *jsonrpc.RPCError
|
||||
if errors.As(err, &rpcErr) && (rpcErr.Code == -32007 /* SLOT_SKIPPED */ || rpcErr.Code == -32004 /* BLOCK_NOT_AVAILABLE */) {
|
||||
out.Lock()
|
||||
fmt.Fprintf(os.Stderr, "slot=%d skipped=true\n", slot)
|
||||
out.Unlock()
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if block == nil {
|
||||
out.Lock()
|
||||
fmt.Fprintf(os.Stderr, "slot=%d empty=true\n", slot)
|
||||
out.Unlock()
|
||||
continue
|
||||
}
|
||||
|
||||
bt := time.Unix(int64(*block.BlockTime), 0)
|
||||
|
||||
out.Lock()
|
||||
json.NewEncoder(os.Stdout).Encode(logLine{TS: bt, Slot: slot, NumTx: len(block.Transactions)})
|
||||
out.Unlock()
|
||||
} else {
|
||||
fmt.Printf("https://explorer.solana.com/block/%d\n", slot)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
for _, slot := range slots {
|
||||
slot := slot + offset
|
||||
if *flagAfter > 0 && slot < *flagAfter {
|
||||
continue
|
||||
}
|
||||
if slot > current {
|
||||
break
|
||||
}
|
||||
|
||||
work <- slot
|
||||
}
|
||||
close(work)
|
||||
|
||||
wg.Wait()
|
||||
}
|
|
@ -1,170 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/gagliardetto/solana-go"
|
||||
"github.com/gagliardetto/solana-go/rpc"
|
||||
"github.com/gagliardetto/solana-go/rpc/ws"
|
||||
"github.com/gagliardetto/solana-go/text"
|
||||
envv1 "go.firedancer.io/radiance/proto/env/v1"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
flagPingerLog = flag.String("pinger_log", "", "JSON log file for pinger")
|
||||
)
|
||||
|
||||
const (
|
||||
confirmPollInterval = time.Second * 5
|
||||
confirmRetries = 10
|
||||
)
|
||||
|
||||
type pingData struct {
|
||||
Slot uint64 `json:"slot"`
|
||||
Ts time.Time `json:"ts"`
|
||||
}
|
||||
|
||||
type logEntry struct {
|
||||
Slot uint64 `json:"slot"`
|
||||
SendDelay time.Duration `json:"send_delay"`
|
||||
Ts time.Time `json:"ts"`
|
||||
Signature solana.Signature `json:"signature"`
|
||||
Leader solana.PublicKey `json:"leader"`
|
||||
|
||||
Confirmed bool `json:"confirmed"`
|
||||
ConfirmedSlot uint64 `json:"confirmed_slot,omitempty"`
|
||||
SlotDelay *int `json:"slot_delay,omitempty"`
|
||||
TimeDelay time.Duration `json:"time_delay,omitempty"`
|
||||
|
||||
Timeout time.Duration `json:"timeout,omitempty"`
|
||||
}
|
||||
|
||||
func buildTransaction(slot uint64, now time.Time, blockhash solana.Hash, feePayer solana.PublicKey) *solana.Transaction {
|
||||
payload := &pingData{Slot: slot, Ts: now}
|
||||
b, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
ins := solana.NewInstruction(solana.MemoProgramID, solana.AccountMetaSlice{}, b)
|
||||
|
||||
tx, err := solana.NewTransaction(
|
||||
[]solana.Instruction{ins}, blockhash, solana.TransactionPayer(feePayer))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return tx
|
||||
}
|
||||
|
||||
func sendPing(ctx context.Context, m *ws.SlotsUpdatesResult, b solana.Hash, signer solana.PrivateKey, g *rpc.GetClusterNodesResult, nodes []*envv1.RPCNode, c map[string]*rpc.Client) {
|
||||
tx := buildTransaction(m.Slot, time.Now(), b, signer.PublicKey())
|
||||
sigs, err := tx.Sign(func(key solana.PublicKey) *solana.PrivateKey {
|
||||
if key != signer.PublicKey() {
|
||||
panic("no private key for unknown signer " + key.String())
|
||||
}
|
||||
return &signer
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if klog.V(2).Enabled() {
|
||||
tx.EncodeTree(text.NewTreeEncoder(os.Stdout, "Ping memo"))
|
||||
}
|
||||
|
||||
txb, err := tx.MarshalBinary()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
klog.Infof("Sending tx %s", sigs[0].String())
|
||||
klog.V(2).Infof("tx: %s", hex.EncodeToString(txb))
|
||||
|
||||
sendUDP(*g.TPU, txb, 20)
|
||||
|
||||
go waitForConfirmation(ctx, m, nodes, c, sigs, g)
|
||||
}
|
||||
|
||||
func waitForConfirmation(ctx context.Context, m *ws.SlotsUpdatesResult, nodes []*envv1.RPCNode, c map[string]*rpc.Client, sigs []solana.Signature, g *rpc.GetClusterNodesResult) {
|
||||
for i := 0; i < confirmRetries; i++ {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-time.After(confirmPollInterval):
|
||||
// pick random node to query status
|
||||
node := nodes[rand.Intn(len(nodes))]
|
||||
st, err := c[node.Name].GetSignatureStatuses(ctx, false, sigs[0])
|
||||
if err != nil {
|
||||
klog.Errorf("Failed to fetch signature status: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, s := range st.Value {
|
||||
if s == nil || s.ConfirmationStatus != rpc.ConfirmationStatusConfirmed {
|
||||
continue
|
||||
}
|
||||
delay := int(s.Slot) - int(m.Slot)
|
||||
klog.Infof("%s confirmed in slot %d (offset %d)", sigs[0], s.Slot, delay)
|
||||
if *flagPingerLog != "" {
|
||||
log(logEntry{
|
||||
Slot: m.Slot,
|
||||
SendDelay: time.Duration(0),
|
||||
Ts: time.Now(),
|
||||
Signature: sigs[0],
|
||||
Leader: g.Pubkey,
|
||||
Confirmed: true,
|
||||
ConfirmedSlot: s.Slot,
|
||||
SlotDelay: &delay,
|
||||
TimeDelay: 0, // TODO - we need precise slot timings for this first
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
klog.Infof("%s failed to confirm after %v",
|
||||
sigs[0].String(), confirmPollInterval*confirmRetries)
|
||||
|
||||
if *flagPingerLog != "" {
|
||||
log(logEntry{
|
||||
Slot: m.Slot,
|
||||
SendDelay: time.Duration(0),
|
||||
Ts: time.Now(),
|
||||
Signature: sigs[0],
|
||||
Leader: g.Pubkey,
|
||||
Confirmed: false,
|
||||
Timeout: confirmPollInterval * confirmRetries,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func log(entry logEntry) {
|
||||
f, err := os.OpenFile(*flagPingerLog, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
klog.Errorf("failed to open %s: %v", *flagPingerLog, err)
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if err := syscall.Flock(int(f.Fd()), syscall.LOCK_EX); err != nil {
|
||||
panic(fmt.Sprintf("failed to lock %s: %v", *flagPingerLog, err))
|
||||
}
|
||||
|
||||
if err := json.NewEncoder(f).Encode(entry); err != nil {
|
||||
klog.Errorf("failed to write to %s: %v", *flagPingerLog, err)
|
||||
}
|
||||
|
||||
if err := syscall.Flock(int(f.Fd()), syscall.LOCK_UN); err != nil {
|
||||
panic(fmt.Sprintf("failed to unlock %s: %v", *flagPingerLog, err))
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
func sendUDP(addr string, txb []byte, count int) {
|
||||
// Send UDP packet to TPU
|
||||
conn, err := net.Dial("udp", addr)
|
||||
if err != nil {
|
||||
// if we fail to open a UDP socket, something has gone really wrong
|
||||
klog.Exitf("failed to dial %s: %v", addr, err)
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
tn := 0
|
||||
for i := 0; i < count; i++ {
|
||||
n, err := conn.Write(txb)
|
||||
if err != nil {
|
||||
klog.Errorf("failed to write to %s: %v", addr, err)
|
||||
}
|
||||
if n != len(txb) {
|
||||
panic(fmt.Errorf("wrote %d bytes, expected %d", n, len(txb)))
|
||||
}
|
||||
tn += n
|
||||
}
|
||||
klog.V(2).Infof("sent %d bytes to %s", tn, addr)
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/gagliardetto/solana-go"
|
||||
)
|
||||
|
||||
func loadLocalSigner() (solana.PrivateKey, error) {
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
key := path.Join(home, ".config/solana/id.json")
|
||||
return solana.PrivateKeyFromSolanaKeygenFile(key)
|
||||
}
|
|
@ -1,154 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/gagliardetto/solana-go"
|
||||
"github.com/gagliardetto/solana-go/rpc"
|
||||
"github.com/gagliardetto/solana-go/rpc/ws"
|
||||
"go.firedancer.io/radiance/pkg/blockhash"
|
||||
"go.firedancer.io/radiance/pkg/clusternodes"
|
||||
"go.firedancer.io/radiance/pkg/envfile"
|
||||
"go.firedancer.io/radiance/pkg/leaderschedule"
|
||||
envv1 "go.firedancer.io/radiance/proto/env/v1"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
flagEnv = flag.String("env", ".env.prototxt", "Env file (.prototxt)")
|
||||
flagOnly = flag.String("only", "", "Only watch specified nodes (comma-separated)")
|
||||
flagPinger = flag.Bool("pinger", false, "Enable pinger")
|
||||
|
||||
flagDebugAddr = flag.String("debugAddr", "localhost:6060", "pprof/metrics listen address")
|
||||
)
|
||||
|
||||
func init() {
|
||||
klog.InitFlags(nil)
|
||||
flag.Parse()
|
||||
}
|
||||
|
||||
func main() {
|
||||
env, err := envfile.Load(*flagEnv)
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed to load env file: %v", err)
|
||||
}
|
||||
|
||||
nodes := env.GetNodes()
|
||||
if len(nodes) == 0 {
|
||||
klog.Fatalf("No nodes found in env file")
|
||||
}
|
||||
|
||||
go func() {
|
||||
klog.Error(http.ListenAndServe(*flagDebugAddr, nil))
|
||||
}()
|
||||
|
||||
nodes = envfile.FilterNodes(nodes, envfile.ParseOnlyFlag(*flagOnly))
|
||||
|
||||
if len(nodes) == 0 {
|
||||
klog.Exitf("No nodes in environment or all nodes filtered")
|
||||
}
|
||||
klog.Infof("Watching %d nodes", len(nodes))
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// Leader schedule helper
|
||||
sched := &leaderschedule.Tracker{}
|
||||
go sched.Run(ctx, env.Nodes)
|
||||
|
||||
// Gossip helper
|
||||
gossip := clusternodes.New(nodes)
|
||||
go gossip.Run(ctx, time.Minute)
|
||||
|
||||
// Blockhash helper
|
||||
bh := blockhash.New(nodes)
|
||||
go bh.Run(ctx, time.Second)
|
||||
|
||||
// Load signing key
|
||||
signer, err := loadLocalSigner()
|
||||
if err != nil {
|
||||
klog.Exitf("Failed to load signing : %v", err)
|
||||
}
|
||||
|
||||
// Cache RPC clients
|
||||
c := make(map[string]*rpc.Client)
|
||||
for _, node := range nodes {
|
||||
c[node.Name] = rpc.New(node.Http)
|
||||
}
|
||||
|
||||
var highest uint64
|
||||
|
||||
for _, node := range nodes {
|
||||
node := node
|
||||
go func() {
|
||||
for {
|
||||
if err := watchSlotUpdates(ctx, node, nodes, sched, gossip, bh, signer, c, &highest); err != nil {
|
||||
klog.Errorf("watchSlotUpdates on node %s, reconnecting: %v", node.Name, err)
|
||||
}
|
||||
time.Sleep(time.Second * 5)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
select {}
|
||||
}
|
||||
|
||||
func watchSlotUpdates(ctx context.Context, node *envv1.RPCNode, nodes []*envv1.RPCNode, sched *leaderschedule.Tracker, gossip *clusternodes.Tracker, bh *blockhash.Tracker, signer solana.PrivateKey, c map[string]*rpc.Client, highest *uint64) error {
|
||||
timeout, cancel := context.WithTimeout(ctx, time.Second*10)
|
||||
defer cancel()
|
||||
|
||||
cw, err := ws.Connect(timeout, node.Ws)
|
||||
if err != nil {
|
||||
return fmt.Errorf("connect: %w", err)
|
||||
}
|
||||
|
||||
sub, err := cw.SlotsUpdatesSubscribe()
|
||||
if err != nil {
|
||||
return fmt.Errorf("subscribe: %w", err)
|
||||
}
|
||||
|
||||
for {
|
||||
m, err := sub.Recv()
|
||||
if err != nil {
|
||||
return fmt.Errorf("recv: %w", err)
|
||||
}
|
||||
|
||||
sched.Update(m.Slot)
|
||||
|
||||
var lastBlockhash solana.Hash
|
||||
|
||||
if m.Type == ws.SlotsUpdatesFirstShredReceived {
|
||||
klog.V(1).Infof("%s: first shred received for slot %d", node.Name, m.Slot)
|
||||
|
||||
if m.Slot > atomic.LoadUint64(highest) {
|
||||
atomic.StoreUint64(highest, m.Slot)
|
||||
klog.Infof("%s: highest slot is now %d", node.Name, m.Slot)
|
||||
leader, ok := sched.TryGet(m.Slot)
|
||||
if !ok {
|
||||
klog.Infof("could not fetch leader for slot %d", m.Slot)
|
||||
continue
|
||||
}
|
||||
g := gossip.GetByPubkey(leader)
|
||||
if g == nil || g.TPU == nil {
|
||||
klog.Infof("could not fetch gossip entry for leader %s", leader)
|
||||
continue
|
||||
}
|
||||
klog.Infof("current leader: %s, tpu: %s", leader, *g.TPU)
|
||||
b := bh.MostRecent()
|
||||
if b != lastBlockhash {
|
||||
klog.Infof("new blockhash: %s", b)
|
||||
lastBlockhash = b
|
||||
}
|
||||
|
||||
if *flagPinger {
|
||||
sendPing(ctx, m, b, signer, g, nodes, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
# solrays
|
||||
|
||||
An RPC proxy that exports call latency of a Solana RPC node.
|
||||
|
||||
## Metrics
|
||||
|
||||
- `solrays_forwarded_duration_seconds` - an histogram of the duration of the calls forwarded to the Solana RPC node, per call.
|
||||
- `solrays_requests_total` - Count of total requests per call.
|
||||
- `solrays_request_errors_total` - Count of total requests that failed, e.g. malformed request or proxy can't reach the Solana RPC node.
|
||||
- `solrays_requests_status_total` - Count of response HTTP status codes, per status code.
|
||||
|
||||
## Run
|
||||
|
||||
```
|
||||
:; _bin/solrays -h
|
||||
```
|
||||
|
||||
Key flags are:
|
||||
|
||||
- `backend` - the Solana RPC endpoint to proxy and monitor. Defaults to `http://localhost:8899`).
|
||||
- `listen` - address where the RPC metrics and Go profiler endpoints are exposed.
|
||||
- `tlsHostname` - the optional hostname for this service. Implicitly enables HTTPS.
|
||||
- `tlsProd` - if HTTPS is enabled, select whether the x509 artifacts are provisioned by the production or the testing Let's Encrypt
|
||||
public ACME service. Defaults to `false`, meaning the testing service will be used.
|
|
@ -1,150 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"net"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/coreos/go-systemd/v22/activation"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
metrics "github.com/slok/go-http-metrics/metrics/prometheus"
|
||||
"github.com/slok/go-http-metrics/middleware"
|
||||
"github.com/slok/go-http-metrics/middleware/std"
|
||||
"golang.org/x/crypto/acme"
|
||||
"golang.org/x/crypto/acme/autocert"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"go.firedancer.io/radiance/pkg/util"
|
||||
)
|
||||
|
||||
var (
|
||||
backendAddr = flag.String("backend", "http://127.0.0.1:8899", "Backend RPC URI to proxy to")
|
||||
debugAddr = flag.String("listen", "[::1]:6060", "pprof and metrics server address")
|
||||
tlsHostname = flag.String("tlsHostname", "", "When set, serve TLS using Let's Encrypt using the hostname in question")
|
||||
tlsProd = flag.Bool("tlsProd", false, "Use the production Let's Encrypt environment")
|
||||
cacheDir = flag.String("cacheDir", "solrays-data", "Cache directory")
|
||||
)
|
||||
|
||||
func init() {
|
||||
klog.CopyStandardLogTo("INFO")
|
||||
klog.InitFlags(nil)
|
||||
flag.Parse()
|
||||
}
|
||||
|
||||
func getSDListeners() []net.Listener {
|
||||
// We use systemd socket activation for (almost) zero downtime deployment -
|
||||
// systemd will keep the socket open even while we restart the process
|
||||
// (plus, it allows us to bind to port 80).
|
||||
//
|
||||
// Read more: https://vincent.bernat.ch/en/blog/2018-systemd-golang-socket-activation
|
||||
|
||||
listeners, err := activation.Listeners()
|
||||
if err != nil {
|
||||
klog.Fatalf("cannot retrieve listeners: %s", err)
|
||||
}
|
||||
if len(listeners) != 1 {
|
||||
klog.Fatalf("unexpected number of sockets passed by systemd (%d != 1)", len(listeners))
|
||||
}
|
||||
|
||||
return listeners
|
||||
}
|
||||
|
||||
func shutdownHandler(server *http.Server) chan struct{} {
|
||||
done := make(chan struct{})
|
||||
quit := make(chan os.Signal, 1)
|
||||
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
go func() {
|
||||
<-quit
|
||||
klog.Info("server is shutting down")
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
server.SetKeepAlivesEnabled(false)
|
||||
if err := server.Shutdown(ctx); err != nil {
|
||||
klog.Exitf("cannot gracefully shut down the server: %s", err)
|
||||
}
|
||||
close(done)
|
||||
}()
|
||||
return done
|
||||
}
|
||||
|
||||
func main() {
|
||||
listeners := getSDListeners()
|
||||
|
||||
// Metrics recording middleware
|
||||
mdlw := middleware.New(middleware.Config{
|
||||
Recorder: metrics.NewRecorder(metrics.Config{}),
|
||||
})
|
||||
|
||||
mux := http.NewServeMux()
|
||||
|
||||
mux.Handle("/", newHandler())
|
||||
|
||||
mux.HandleFunc("/health", func(w http.ResponseWriter, req *http.Request) {
|
||||
klog.V(1).Infof("[%s] %s %s %v", req.RemoteAddr, req.Method, req.URL, req.Header)
|
||||
w.Write([]byte("ok"))
|
||||
})
|
||||
|
||||
wrapped := std.Handler("default", mdlw, mux)
|
||||
|
||||
server := &http.Server{
|
||||
Handler: wrapped,
|
||||
ReadTimeout: readTimeout,
|
||||
WriteTimeout: requestTimeout,
|
||||
}
|
||||
|
||||
// Setup TLS if an hostname has been specified.
|
||||
if *tlsHostname != "" {
|
||||
// Proceed only if a valid hostname has been specified.
|
||||
if util.IsValidHostname(*tlsHostname) {
|
||||
klog.Fatalf("tlsHostname [%s] is an invalid hostname, exiting", *tlsHostname)
|
||||
}
|
||||
|
||||
klog.Infof("provisioning Let's Encrypt certificate for %s", *tlsHostname)
|
||||
|
||||
var acmeApi string
|
||||
if *tlsProd {
|
||||
klog.Infof("using production Let's Encrypt server")
|
||||
acmeApi = autocert.DefaultACMEDirectory
|
||||
} else {
|
||||
klog.Infof("using staging Let's Encrypt server")
|
||||
acmeApi = "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
}
|
||||
|
||||
certManager := autocert.Manager{
|
||||
Prompt: autocert.AcceptTOS,
|
||||
HostPolicy: autocert.HostWhitelist(*tlsHostname),
|
||||
Cache: autocert.DirCache(path.Join(*cacheDir, "autocert")),
|
||||
Client: &acme.Client{DirectoryURL: acmeApi},
|
||||
}
|
||||
|
||||
server.TLSConfig = certManager.TLSConfig()
|
||||
klog.Info("certificate provisioning configured")
|
||||
}
|
||||
|
||||
// Graceful shutdown
|
||||
done := shutdownHandler(server)
|
||||
|
||||
go func() {
|
||||
http.Handle("/metrics", promhttp.Handler())
|
||||
klog.Infof("debug server listening on %s", *debugAddr)
|
||||
klog.Exit(http.ListenAndServe(*debugAddr, nil))
|
||||
}()
|
||||
|
||||
if *tlsHostname != "" {
|
||||
klog.Infof("main server listening with TLS on %s", listeners[0].Addr())
|
||||
klog.Exit(server.ServeTLS(listeners[0], "", ""))
|
||||
} else {
|
||||
klog.Infof("main server listening on %s", listeners[0].Addr())
|
||||
klog.Exit(server.Serve(listeners[0]))
|
||||
}
|
||||
|
||||
<-done
|
||||
}
|
|
@ -1,162 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"k8s.io/klog/v2"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type (
|
||||
rpcRequest struct {
|
||||
Version string `json:"jsonrpc"`
|
||||
ID interface{} `json:"id"`
|
||||
Method string `json:"method"`
|
||||
Params []interface{} `json:"params"`
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
invalidRequestMessage = "Not a valid JSONRPC POST request\n"
|
||||
maxRequestSize = 1024 * 10 // 10 KiB
|
||||
|
||||
// Duration the entire request is allowed to take, including the backend request and response writing.
|
||||
requestTimeout = 10 * time.Second
|
||||
// Read timeout for request body and headers.
|
||||
readTimeout = 2 * time.Second
|
||||
)
|
||||
|
||||
var (
|
||||
httpDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{
|
||||
Name: "solrays_forwarded_duration_seconds",
|
||||
Help: "Duration of HTTP requests that made it to the backend",
|
||||
}, []string{"method"})
|
||||
|
||||
requestsTotal = promauto.NewCounterVec(prometheus.CounterOpts{
|
||||
Name: "solrays_requests_total",
|
||||
Help: "Number of requests per method",
|
||||
}, []string{"method"})
|
||||
|
||||
requestErrors = promauto.NewCounterVec(prometheus.CounterOpts{
|
||||
Name: "solrays_request_errors_total",
|
||||
Help: "Number of failed requests",
|
||||
}, []string{"reason"})
|
||||
|
||||
backendRequest = promauto.NewCounterVec(prometheus.CounterOpts{
|
||||
Name: "solrays_requests_status_total",
|
||||
Help: "Number of backend responses by method and status code",
|
||||
}, []string{"method", "code"})
|
||||
)
|
||||
|
||||
type handler struct {
|
||||
client *http.Client
|
||||
}
|
||||
|
||||
func newHandler() handler {
|
||||
return handler{&http.Client{}}
|
||||
}
|
||||
|
||||
func (h handler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
start := time.Now()
|
||||
klog.V(2).Infof("[%s] %s %s %v", req.RemoteAddr, req.Method, req.URL, req.Header)
|
||||
|
||||
if req.Method == "OPTIONS" {
|
||||
h.sendCORS(w)
|
||||
return
|
||||
}
|
||||
|
||||
if req.Method != "POST" {
|
||||
requestErrors.WithLabelValues("wrong_method").Inc()
|
||||
http.Error(w, invalidRequestMessage, http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
if req.Header.Get("Content-Type") != "application/json" {
|
||||
requestErrors.WithLabelValues("wrong_content_type").Inc()
|
||||
http.Error(w, invalidRequestMessage, http.StatusUnsupportedMediaType)
|
||||
return
|
||||
}
|
||||
|
||||
h.sendCORS(w)
|
||||
|
||||
ctx, cancel := context.WithTimeout(req.Context(), requestTimeout)
|
||||
defer cancel()
|
||||
|
||||
// We need to read the entire request in order to decode and parse it.
|
||||
b, err := ioutil.ReadAll(http.MaxBytesReader(w, req.Body, maxRequestSize))
|
||||
if err != nil {
|
||||
requestErrors.WithLabelValues("reading_body").Inc()
|
||||
http.Error(w, "Error reading request body", http.StatusRequestTimeout)
|
||||
klog.V(1).Infof("[%s] (+%v) failed to read request body: %v",
|
||||
req.RemoteAddr, time.Since(start), err)
|
||||
return
|
||||
}
|
||||
|
||||
klog.V(3).Infof("[%s] raw request: %s", req.RemoteAddr, string(b))
|
||||
|
||||
var rpc rpcRequest
|
||||
if err = json.Unmarshal(b, &rpc); err != nil {
|
||||
requestErrors.WithLabelValues("decoding_request").Inc()
|
||||
http.Error(w, "Error decoding request", http.StatusBadRequest)
|
||||
klog.V(1).Infof("[%s] (+%v) failed to decode request: %v",
|
||||
req.RemoteAddr, time.Since(start), err)
|
||||
return
|
||||
}
|
||||
|
||||
klog.V(2).Infof("[%s] (+%v) request: %v", req.RemoteAddr, time.Since(start), rpc)
|
||||
|
||||
if _, ok := methodWhitelistMap[rpc.Method]; !ok {
|
||||
requestErrors.WithLabelValues("invalid_method").Inc()
|
||||
http.Error(w, "Invalid RPC method", http.StatusBadRequest)
|
||||
klog.V(1).Infof("[%s] (+%v) called a method not on the whitelist: %s",
|
||||
req.RemoteAddr, time.Since(start), rpc.Method)
|
||||
return
|
||||
}
|
||||
|
||||
requestsTotal.WithLabelValues(rpc.Method).Inc()
|
||||
|
||||
r, err := http.NewRequestWithContext(ctx, "POST", *backendAddr, bytes.NewBuffer(b))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
r.Header = req.Header
|
||||
|
||||
reqs := time.Now()
|
||||
res, err := h.client.Do(r)
|
||||
if err != nil {
|
||||
http.Error(w, "Bad Gateway", http.StatusBadGateway)
|
||||
requestErrors.WithLabelValues("backend_request").Inc()
|
||||
klog.Warningf("[%s] (+%v) [%s] backend request failed: %v",
|
||||
req.RemoteAddr, rpc.ID, reqs.Sub(start), err)
|
||||
return
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
backendRequest.WithLabelValues(rpc.Method, strconv.Itoa(res.StatusCode)).Inc()
|
||||
klog.V(1).Infof("[%s] (+%v) [%s] %s request returned status %d in %v",
|
||||
req.RemoteAddr, time.Since(start), rpc.ID, rpc.Method, res.StatusCode, time.Since(reqs))
|
||||
w.WriteHeader(res.StatusCode)
|
||||
|
||||
n, err := io.Copy(w, res.Body)
|
||||
klog.V(1).Infof("[%s] (+%v) [%s] wrote %d bytes", req.RemoteAddr, time.Since(start), rpc.ID, n)
|
||||
d := time.Since(start)
|
||||
if err != nil {
|
||||
klog.V(1).Infof("[%s] (+%v) [%s] failed writing response: %v",
|
||||
req.RemoteAddr, d, rpc.ID, err)
|
||||
}
|
||||
|
||||
httpDuration.WithLabelValues(rpc.Method).Observe(d.Seconds())
|
||||
}
|
||||
|
||||
func (h handler) sendCORS(w http.ResponseWriter) {
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
package main
|
||||
|
||||
var (
|
||||
// https://docs.solana.com/developing/clients/jsonrpc-api
|
||||
methodWhitelist = []string{
|
||||
// Stable
|
||||
"getAccountInfo",
|
||||
"getBalance",
|
||||
"getBlock",
|
||||
"getBlockHeight",
|
||||
"getBlockProduction",
|
||||
"getBlockCommitment",
|
||||
"getBlocks",
|
||||
"getBlocksWithLimit",
|
||||
"getBlockTime",
|
||||
"getClusterNodes",
|
||||
"getEpochInfo",
|
||||
"getEpochSchedule",
|
||||
"getFeeForMessage",
|
||||
"getFirstAvailableBlock",
|
||||
"getGenesisHash",
|
||||
"getHealth",
|
||||
"getHighestSnapshotSlot",
|
||||
"getIdentity",
|
||||
"getInflationGovernor",
|
||||
"getInflationRate",
|
||||
"getInflationReward",
|
||||
"getLargestAccounts",
|
||||
"getLatestBlockhash",
|
||||
"getLeaderSchedule",
|
||||
"getMaxRetransmitSlot",
|
||||
"getMaxShredInsertSlot",
|
||||
"getMinimumBalanceForRentExemption",
|
||||
"getMultipleAccounts",
|
||||
"getProgramAccounts",
|
||||
"getRecentPerformanceSamples",
|
||||
"getSignaturesForAddress",
|
||||
"getSignatureStatuses",
|
||||
"getSlot",
|
||||
"getSlotLeader",
|
||||
"getSlotLeaders",
|
||||
"getStakeActivation",
|
||||
"getStakeMinimumDelegation",
|
||||
"getSupply",
|
||||
"getTokenAccountBalance",
|
||||
"getTokenAccountsByDelegate",
|
||||
"getTokenAccountsByOwner",
|
||||
"getTokenLargestAccounts",
|
||||
"getTokenSupply",
|
||||
"getTransaction",
|
||||
"getTransactionCount",
|
||||
"getVersion",
|
||||
"getVoteAccounts",
|
||||
"isBlockhashValid",
|
||||
"minimumLedgerSlot",
|
||||
"requestAirdrop",
|
||||
"sendTransaction",
|
||||
"simulateTransaction",
|
||||
|
||||
// Deprecated
|
||||
"getConfirmedBlock",
|
||||
"getConfirmedBlocks",
|
||||
"getConfirmedBlocksWithLimit",
|
||||
"getConfirmedSignaturesForAddress2",
|
||||
"getConfirmedTransaction",
|
||||
"getFeeCalculatorForBlockhash",
|
||||
"getFeeRateGovernor",
|
||||
"getFees",
|
||||
"getRecentBlockhash",
|
||||
"getSnapshotSlot",
|
||||
}
|
||||
|
||||
methodWhitelistMap = make(map[string]bool)
|
||||
)
|
||||
|
||||
func init() {
|
||||
for _, v := range methodWhitelist {
|
||||
methodWhitelistMap[v] = true
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
|
||||
import requests
|
||||
|
||||
RADIANCE_HOST = os.getenv("RADIANCE_HOST")
|
||||
RADIANCE_USER = os.getenv("RADIANCE_USER")
|
||||
RADIANCE_PASSWORD = os.getenv("RADIANCE_PASSWORD")
|
||||
|
||||
LEADER_STATS = """
|
||||
SELECT
|
||||
floor(slot, -3) as slotWindow,
|
||||
leader,
|
||||
median(diff) AS medianReplay,
|
||||
count() AS count
|
||||
FROM
|
||||
(
|
||||
WITH
|
||||
leader,
|
||||
minIf(timestamp, type = 'firstShredReceived') AS tsReceived,
|
||||
minIf(timestamp, type = 'completed') AS tsCompleted
|
||||
SELECT
|
||||
source,
|
||||
slot,
|
||||
leader,
|
||||
toUnixTimestamp64Milli(tsCompleted) - toUnixTimestamp64Milli(tsReceived) AS diff
|
||||
FROM slot_status
|
||||
WHERE toDate(timestamp) = today() - 5
|
||||
GROUP BY
|
||||
slot,
|
||||
leader,
|
||||
source
|
||||
HAVING diff > 0
|
||||
)
|
||||
GROUP BY slotWindow, leader
|
||||
ORDER BY median(diff)"""
|
||||
|
||||
|
||||
class RadianceClient():
|
||||
def __init__(self, host, user, password):
|
||||
self.host = host
|
||||
self.user = user
|
||||
self.password = password
|
||||
self.session = requests.session()
|
||||
self.session.user_agent = "radiance-client/v0.1"
|
||||
self.session.auth = (self.user, self.password)
|
||||
|
||||
def query(self, query):
|
||||
r = self.session.post(self.host, data=query + "\nFORMAT JSON")
|
||||
if r.status_code != 200:
|
||||
raise Exception("Failed to get leader stats: {}".format(r.text))
|
||||
return r.json()['data']
|
||||
|
||||
def get_leader_stats(self):
|
||||
return self.query(LEADER_STATS)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import json
|
||||
c = RadianceClient(RADIANCE_HOST, RADIANCE_USER, RADIANCE_PASSWORD)
|
||||
r = c.get_leader_stats()
|
||||
print(json.dumps(r, indent=2))
|
|
@ -1 +0,0 @@
|
|||
out
|
|
@ -1 +0,0 @@
|
|||
SELECT max(slot) FROM slot_status WHERE toDate(timestamp) = today()
|
|
@ -1,13 +0,0 @@
|
|||
SELECT slot,
|
||||
timestamp,
|
||||
runningDifference(toUnixTimestamp64Milli(timestamp)) AS deltaMs,
|
||||
bar(deltaMs, 0, 10000, 10) AS deltaMsB,
|
||||
type
|
||||
FROM (
|
||||
SELECT *
|
||||
FROM slot_status
|
||||
WHERE (slot = 138604605)
|
||||
AND (source = 'val4.ffm1')
|
||||
ORDER BY timestamp ASC,
|
||||
type ASC
|
||||
)
|
|
@ -1,9 +0,0 @@
|
|||
WITH CAST(timestamp, 'Nullable(DateTime)') AS ts
|
||||
SELECT
|
||||
slot,
|
||||
minIf(ts, type = 'firstShredReceived') AS first,
|
||||
minIf(ts, type = 'completed') AS completed,
|
||||
minIf(ts, type = 'optimisticConfirmation') AS confirmed
|
||||
FROM slot_status
|
||||
GROUP BY slot
|
||||
ORDER BY slot ASC
|
|
@ -1,4 +0,0 @@
|
|||
select leader, avg(stats.num_successful_transactions + assumeNotNull(stats.num_failed_transactions)) as avgTxs
|
||||
from slot_status
|
||||
group by leader
|
||||
order by avgTxs desc
|
|
@ -1,7 +0,0 @@
|
|||
SELECT
|
||||
slot,
|
||||
max(assumeNotNull(stats.num_successful_transactions)) + max(assumeNotNull(stats.num_failed_transactions)) AS maxTxs
|
||||
FROM slot_status
|
||||
WHERE type = 'frozen'
|
||||
GROUP BY slot
|
||||
ORDER BY slot
|
|
@ -1,29 +0,0 @@
|
|||
SELECT
|
||||
winner,
|
||||
count(),
|
||||
bar(count(), 1, 10000, 20)
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
slot,
|
||||
any(source) AS winner
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
source,
|
||||
slot,
|
||||
minIf(timestamp, type = 'completed') AS firstCompleted
|
||||
FROM slot_status
|
||||
WHERE toDate(timestamp) = today()
|
||||
GROUP BY
|
||||
source,
|
||||
slot
|
||||
ORDER BY
|
||||
slot ASC,
|
||||
firstCompleted ASC
|
||||
)
|
||||
GROUP BY slot
|
||||
ORDER BY slot ASC
|
||||
)
|
||||
GROUP BY winner
|
||||
ORDER BY count() DESC
|
|
@ -1,60 +0,0 @@
|
|||
CREATE TABLE heimdall_queue
|
||||
(
|
||||
bankSlot UInt64,
|
||||
bankID UInt64,
|
||||
bankParentHash String,
|
||||
feePayer String,
|
||||
signature String,
|
||||
program String,
|
||||
"timings.serialize_us" UInt64,
|
||||
"timings.create_vm_us" UInt64,
|
||||
"timings.execute_us" UInt64,
|
||||
"timings.deserialize_us" UInt64,
|
||||
"timings.get_or_create_executor_us" UInt64,
|
||||
"timings.changed_account_count" UInt64,
|
||||
"timings.total_account_count" UInt64,
|
||||
"timings.total_data_size" UInt64,
|
||||
"timings.data_size_changed" UInt64,
|
||||
"timings.create_executor_register_syscalls_us" UInt64,
|
||||
"timings.create_executor_load_elf_us" UInt64,
|
||||
"timings.create_executor_verify_code_us" UInt64,
|
||||
"timings.create_executor_jit_compile_us" UInt64
|
||||
) ENGINE = Kafka()
|
||||
SETTINGS
|
||||
kafka_broker_list = '<snip>:30036',
|
||||
kafka_topic_list = 'certus.radiance.heimdall',
|
||||
kafka_group_name = 'heimdall-chdev1',
|
||||
kafka_format = 'Protobuf',
|
||||
kafka_max_block_size = 1048576,
|
||||
format_schema = 'heimdall.proto:Observation';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS heimdall
|
||||
(
|
||||
timestamp DateTime64,
|
||||
bankSlot UInt64,
|
||||
bankID UInt64,
|
||||
bankParentHash String,
|
||||
feePayer String,
|
||||
signature String,
|
||||
program String,
|
||||
"timings.serialize_us" UInt64,
|
||||
"timings.create_vm_us" UInt64,
|
||||
"timings.execute_us" UInt64,
|
||||
"timings.deserialize_us" UInt64,
|
||||
"timings.get_or_create_executor_us" UInt64,
|
||||
"timings.changed_account_count" UInt64,
|
||||
"timings.total_account_count" UInt64,
|
||||
"timings.total_data_size" UInt64,
|
||||
"timings.data_size_changed" UInt64,
|
||||
"timings.create_executor_register_syscalls_us" UInt64,
|
||||
"timings.create_executor_load_elf_us" UInt64,
|
||||
"timings.create_executor_verify_code_us" UInt64,
|
||||
"timings.create_executor_jit_compile_us" UInt64
|
||||
) ENGINE = MergeTree()
|
||||
PARTITION BY toStartOfHour(timestamp)
|
||||
ORDER BY bankSlot;
|
||||
|
||||
CREATE MATERIALIZED VIEW IF NOT EXISTS heimdall_view TO heimdall
|
||||
AS
|
||||
SELECT _timestamp_ms AS timestamp, *
|
||||
FROM heimdall_queue;
|
|
@ -1,73 +0,0 @@
|
|||
CREATE TABLE IF NOT EXISTS slot_status_queue
|
||||
(
|
||||
slot UInt64,
|
||||
timestamp UInt64,
|
||||
delay UInt64,
|
||||
type Enum8(
|
||||
'unspecified' = 0,
|
||||
'firstShredReceived' = 1,
|
||||
'completed' = 2,
|
||||
'createdBank' = 3,
|
||||
'frozen' = 4,
|
||||
'dead' = 5,
|
||||
'optimisticConfirmation' = 6,
|
||||
'root' = 7
|
||||
),
|
||||
|
||||
source String,
|
||||
leader String,
|
||||
|
||||
parent UInt64,
|
||||
|
||||
"stats.num_transaction_entries" Nullable(UInt64),
|
||||
"stats.num_successful_transactions" Nullable(UInt64),
|
||||
"stats.num_failed_transactions" Nullable(UInt64),
|
||||
"stats.max_transactions_per_entry" Nullable(UInt64),
|
||||
|
||||
err String
|
||||
) ENGINE = Kafka()
|
||||
SETTINGS
|
||||
kafka_broker_list = '<snip>:30036',
|
||||
kafka_topic_list = 'certus.radiance.slot_status',
|
||||
kafka_group_name = 'heimdall-chdev1',
|
||||
kafka_format = 'Protobuf',
|
||||
kafka_max_block_size = 32,
|
||||
format_schema = 'network.proto:SlotStatus';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS slot_status
|
||||
(
|
||||
slot UInt64,
|
||||
timestamp DateTime64(3),
|
||||
delay UInt64,
|
||||
type Enum8(
|
||||
'unspecified' = 0,
|
||||
'firstShredReceived' = 1,
|
||||
'completed' = 2,
|
||||
'createdBank' = 3,
|
||||
'frozen' = 4,
|
||||
'dead' = 5,
|
||||
'optimisticConfirmation' = 6,
|
||||
'root' = 7
|
||||
),
|
||||
|
||||
|
||||
source String,
|
||||
leader String,
|
||||
|
||||
parent UInt64,
|
||||
|
||||
"stats.num_transaction_entries" Nullable(UInt64),
|
||||
"stats.num_successful_transactions" Nullable(UInt64),
|
||||
"stats.num_failed_transactions" Nullable(UInt64),
|
||||
"stats.max_transactions_per_entry" Nullable(UInt64),
|
||||
|
||||
err String
|
||||
) ENGINE = MergeTree()
|
||||
PARTITION BY toDate(timestamp)
|
||||
ORDER BY (slot, type, leader);
|
||||
|
||||
CREATE MATERIALIZED VIEW IF NOT EXISTS slot_status_view TO slot_status
|
||||
AS
|
||||
SELECT fromUnixTimestamp64Milli(timestamp) AS timestamp,
|
||||
* EXCEPT ( timestamp )
|
||||
FROM slot_status_queue;
|
12
go.mod
12
go.mod
|
@ -7,12 +7,10 @@ require (
|
|||
github.com/LiamHaworth/go-tproxy v0.0.0-20190726054950-ef7efd7f24ed
|
||||
github.com/VividCortex/ewma v1.2.0
|
||||
github.com/cespare/xxhash/v2 v2.2.0
|
||||
github.com/coreos/go-systemd/v22 v22.5.0
|
||||
github.com/filecoin-project/go-leb128 v0.0.0-20190212224330-8d79a5489543
|
||||
github.com/gagliardetto/binary v0.7.8
|
||||
github.com/gagliardetto/solana-go v1.8.3-0.20230302093440-c6043ec381e3
|
||||
github.com/go-logr/logr v1.2.3
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/google/gopacket v1.1.19
|
||||
github.com/google/nftables v0.1.0
|
||||
github.com/ipfs/go-cid v0.3.2
|
||||
|
@ -32,13 +30,10 @@ require (
|
|||
github.com/novifinancial/serde-reflection/serde-generate/runtime/golang v0.0.0-20220519162058-e5cd3c3b3f3a
|
||||
github.com/prometheus/client_golang v1.14.0
|
||||
github.com/segmentio/textio v1.2.0
|
||||
github.com/slok/go-http-metrics v0.10.0
|
||||
github.com/spaolacci/murmur3 v1.1.0
|
||||
github.com/spf13/cobra v1.6.1
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/twmb/franz-go v1.12.1
|
||||
github.com/vbauerster/mpb/v8 v8.2.1
|
||||
golang.org/x/crypto v0.7.0
|
||||
golang.org/x/sync v0.1.0
|
||||
golang.org/x/sys v0.6.0
|
||||
google.golang.org/protobuf v1.29.0
|
||||
|
@ -58,7 +53,6 @@ require (
|
|||
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/blendle/zapdriver v1.3.1 // indirect
|
||||
github.com/buger/jsonparser v1.1.1 // indirect
|
||||
github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect
|
||||
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20220520190051-1e77728a1eaa // indirect
|
||||
|
@ -75,12 +69,11 @@ require (
|
|||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.7.0 // indirect
|
||||
github.com/gorilla/rpc v1.2.0 // indirect
|
||||
github.com/gorilla/websocket v1.4.2 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/ipfs/bbloom v0.0.4 // indirect
|
||||
|
@ -122,7 +115,6 @@ require (
|
|||
github.com/onsi/ginkgo v1.16.5 // indirect
|
||||
github.com/onsi/gomega v1.15.0 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.15 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/polydawn/refmt v0.89.0 // indirect
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
|
@ -132,7 +124,6 @@ require (
|
|||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/streamingfast/logging v0.0.0-20221209193439-bff11742bf4c // indirect
|
||||
github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569 // indirect
|
||||
github.com/twmb/franz-go/pkg/kmsg v1.4.0 // indirect
|
||||
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect
|
||||
github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa // indirect
|
||||
go.mongodb.org/mongo-driver v1.11.2 // indirect
|
||||
|
@ -143,6 +134,7 @@ require (
|
|||
go.uber.org/multierr v1.10.0 // indirect
|
||||
go.uber.org/ratelimit v0.2.0 // indirect
|
||||
go.uber.org/zap v1.24.0 // indirect
|
||||
golang.org/x/crypto v0.7.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230304125523-9ff063c70017 // indirect
|
||||
golang.org/x/mod v0.9.0 // indirect
|
||||
golang.org/x/net v0.8.0 // indirect
|
||||
|
|
18
go.sum
18
go.sum
|
@ -99,7 +99,6 @@ github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHf
|
|||
github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc=
|
||||
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
||||
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
|
||||
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk=
|
||||
|
@ -126,8 +125,6 @@ github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc
|
|||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
|
@ -171,6 +168,7 @@ github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmV
|
|||
github.com/gagliardetto/binary v0.7.7/go.mod h1:mUuay5LL8wFVnIlecHakSZMvcdqfs+CsotR5n77kyjM=
|
||||
github.com/gagliardetto/binary v0.7.8 h1:hbIUIP8BWhPm/BIdODxY2Lnv4NlJwNdbtsi1xkhNOec=
|
||||
github.com/gagliardetto/binary v0.7.8/go.mod h1:Cn70Gnvyk1OWkNJXwVh3oYqSYhKLHJN+C/Wguw3fc3U=
|
||||
github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw=
|
||||
github.com/gagliardetto/gofuzz v1.2.2/go.mod h1:bkH/3hYLZrMLbfYWA0pWzXmi5TTRZnu4pMGZBkqMKvY=
|
||||
github.com/gagliardetto/solana-go v1.8.3-0.20230302093440-c6043ec381e3 h1:PtvmSQDTpZ1mwN1t7UlCrUhTyEozJhF3ixuO1m0+9q0=
|
||||
github.com/gagliardetto/solana-go v1.8.3-0.20230302093440-c6043ec381e3/go.mod h1:i+7aAyNDTHG0jK8GZIBSI4OVvDqkt2Qx+LklYclRNG8=
|
||||
|
@ -200,7 +198,6 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me
|
|||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
|
@ -289,9 +286,7 @@ github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1Yu
|
|||
github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/rpc v1.2.0 h1:WvvdC2lNeT1SP32zrIce5l0ECBfbAlmrmSBsuc57wfk=
|
||||
github.com/gorilla/rpc v1.2.0/go.mod h1:V4h9r+4sF5HnzqbwIez0fKSpANP0zlYd3qR7p36jkTQ=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
|
@ -427,7 +422,6 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
|
|||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
|
||||
github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4=
|
||||
github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
|
@ -577,8 +571,6 @@ github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYr
|
|||
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0=
|
||||
github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
|
@ -668,8 +660,6 @@ github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5k
|
|||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/slok/go-http-metrics v0.10.0 h1:rh0LaYEKza5eaYRGDXujKrOln57nHBi4TtVhmNEpbgM=
|
||||
github.com/slok/go-http-metrics v0.10.0/go.mod h1:lFqdaS4kWMfUKCSukjC47PdCeTk+hXDUVm8kLHRqJ38=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
|
||||
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
|
||||
|
@ -702,7 +692,6 @@ github.com/streamingfast/logging v0.0.0-20221209193439-bff11742bf4c/go.mod h1:Vl
|
|||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
|
@ -729,10 +718,6 @@ github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhV
|
|||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/twmb/franz-go v1.12.1 h1:8lWT8q0spL40Nfw6eonJ8OoPGLvF9arvadRRmcSiu9Y=
|
||||
github.com/twmb/franz-go v1.12.1/go.mod h1:Ofc5tSSUJKLmpRNUYSejUsAZKYAHDHywTS322KWdChQ=
|
||||
github.com/twmb/franz-go/pkg/kmsg v1.4.0 h1:tbp9hxU6m8qZhQTlpGiaIJOm4BXix5lsuEZ7K00dF0s=
|
||||
github.com/twmb/franz-go/pkg/kmsg v1.4.0/go.mod h1:SxG/xJKhgPu25SamAq0rrucfp7lbzCpEXOC+vH/ELrY=
|
||||
github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
|
@ -821,7 +806,6 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
|||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
|
|
|
@ -1,122 +0,0 @@
|
|||
package blockhash
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gagliardetto/solana-go"
|
||||
"github.com/gagliardetto/solana-go/rpc"
|
||||
envv1 "go.firedancer.io/radiance/proto/env/v1"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
type Tracker struct {
|
||||
mu sync.Mutex
|
||||
byNode map[string]struct {
|
||||
Blockhash solana.Hash
|
||||
HighestValidSlot uint64
|
||||
}
|
||||
nodes []*envv1.RPCNode
|
||||
|
||||
c map[string]*rpc.Client
|
||||
}
|
||||
|
||||
func New(nodes []*envv1.RPCNode) *Tracker {
|
||||
t := &Tracker{
|
||||
byNode: make(map[string]struct {
|
||||
Blockhash solana.Hash
|
||||
HighestValidSlot uint64
|
||||
}),
|
||||
c: make(map[string]*rpc.Client),
|
||||
nodes: nodes,
|
||||
}
|
||||
|
||||
for _, node := range nodes {
|
||||
t.c[node.Name] = rpc.New(node.Http)
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
func (t *Tracker) MostPopular() solana.Hash {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
|
||||
// Return the most frequently occurring value of t.byNode
|
||||
var mostPopular solana.Hash
|
||||
var mostPopularCount int
|
||||
for _, h := range t.byNode {
|
||||
count := 0
|
||||
for _, h2 := range t.byNode {
|
||||
if h.Blockhash.Equals(h2.Blockhash) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
if count > mostPopularCount {
|
||||
mostPopular = h.Blockhash
|
||||
mostPopularCount = count
|
||||
}
|
||||
|
||||
klog.V(2).Infof("%s: %d", h, count)
|
||||
}
|
||||
return mostPopular
|
||||
}
|
||||
|
||||
func (t *Tracker) MostRecent() solana.Hash {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
|
||||
// Return the blockhash which has the highest valid slot
|
||||
var mostRecent solana.Hash
|
||||
var highestValidSlot uint64
|
||||
for _, h := range t.byNode {
|
||||
if h.HighestValidSlot > highestValidSlot {
|
||||
highestValidSlot = h.HighestValidSlot
|
||||
mostRecent = h.Blockhash
|
||||
}
|
||||
}
|
||||
return mostRecent
|
||||
}
|
||||
|
||||
func (t *Tracker) Run(ctx context.Context, interval time.Duration) {
|
||||
t.update(ctx)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-time.After(interval):
|
||||
t.update(ctx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tracker) update(ctx context.Context) {
|
||||
now := time.Now()
|
||||
|
||||
for _, node := range t.nodes {
|
||||
node := node
|
||||
go func() {
|
||||
ctx, cancel := context.WithTimeout(ctx, time.Second*5)
|
||||
defer cancel()
|
||||
klog.V(1).Infof("Fetching blockhash from %s", node.Http)
|
||||
h, err := t.c[node.Name].GetLatestBlockhash(ctx, rpc.CommitmentConfirmed)
|
||||
if err != nil {
|
||||
klog.Errorf("%s: failed to request blockhash: %v", node.Name, err)
|
||||
return
|
||||
}
|
||||
|
||||
klog.V(1).Infof("%s: fetched blockhash %d -> %s in %v",
|
||||
node.Name, h.Value.LastValidBlockHeight, h.Value.Blockhash, time.Since(now))
|
||||
t.mu.Lock()
|
||||
t.byNode[node.Name] = struct {
|
||||
Blockhash solana.Hash
|
||||
HighestValidSlot uint64
|
||||
}{
|
||||
Blockhash: h.Value.Blockhash,
|
||||
HighestValidSlot: h.Value.LastValidBlockHeight,
|
||||
}
|
||||
t.mu.Unlock()
|
||||
}()
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
package clusternodes
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/rand"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gagliardetto/solana-go"
|
||||
"github.com/gagliardetto/solana-go/rpc"
|
||||
envv1 "go.firedancer.io/radiance/proto/env/v1"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
type Tracker struct {
|
||||
mu sync.Mutex
|
||||
current []*rpc.GetClusterNodesResult
|
||||
byPubkey map[solana.PublicKey]*rpc.GetClusterNodesResult
|
||||
c map[string]*rpc.Client
|
||||
nodes []*envv1.RPCNode
|
||||
}
|
||||
|
||||
func New(nodes []*envv1.RPCNode) *Tracker {
|
||||
c := make(map[string]*rpc.Client)
|
||||
for _, node := range nodes {
|
||||
c[node.Name] = rpc.New(node.Http)
|
||||
}
|
||||
|
||||
return &Tracker{
|
||||
byPubkey: make(map[solana.PublicKey]*rpc.GetClusterNodesResult),
|
||||
c: c,
|
||||
nodes: nodes,
|
||||
}
|
||||
}
|
||||
|
||||
// Run periodically fetches the gossip
|
||||
func (t *Tracker) Run(ctx context.Context, interval time.Duration) {
|
||||
t.update(ctx)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-time.After(interval):
|
||||
t.update(ctx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tracker) update(ctx context.Context) {
|
||||
now := time.Now()
|
||||
|
||||
// Fetch gossip
|
||||
node := t.nodes[rand.Intn(len(t.nodes))]
|
||||
c := t.c[node.Name]
|
||||
klog.Infof("Fetching cluster nodes from %s", node.Http)
|
||||
out, err := c.GetClusterNodes(ctx)
|
||||
if err != nil {
|
||||
klog.Errorf("Failed to update cluster nodes: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
klog.Infof("Fetched %d nodes in %v", len(out), time.Since(now))
|
||||
|
||||
t.mu.Lock()
|
||||
t.current = out
|
||||
for _, n := range out {
|
||||
t.byPubkey[n.Pubkey] = n
|
||||
}
|
||||
t.mu.Unlock()
|
||||
}
|
||||
|
||||
func (t *Tracker) GetByPubkey(pubkey solana.PublicKey) *rpc.GetClusterNodesResult {
|
||||
t.mu.Lock()
|
||||
entry := t.byPubkey[pubkey]
|
||||
t.mu.Unlock()
|
||||
return entry
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
package envfile
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
envv1 "go.firedancer.io/radiance/proto/env/v1"
|
||||
"google.golang.org/protobuf/encoding/prototext"
|
||||
)
|
||||
|
||||
// Load loads the environment config from the given prototxt file.
|
||||
func Load(filename string) (*envv1.Env, error) {
|
||||
b, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read env file: %w", err)
|
||||
}
|
||||
|
||||
var env envv1.Env
|
||||
err = prototext.Unmarshal(b, &env)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal env file: %w", err)
|
||||
}
|
||||
|
||||
return &env, nil
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package envfile
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
envv1 "go.firedancer.io/radiance/proto/env/v1"
|
||||
)
|
||||
|
||||
func TestLoadEnvFile(t *testing.T) {
|
||||
env, err := Load("testdata/env.prototxt")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if env.Nodes[0].Name != "localhost" {
|
||||
t.Errorf("Expected node name to be 'localhost', got '%s'", env.Nodes[0].Name)
|
||||
}
|
||||
|
||||
if len(env.Nodes) != 2 {
|
||||
t.Errorf("Expected 2 node, got %d", len(env.Nodes))
|
||||
}
|
||||
|
||||
if len(env.Kafka.Brokers) != 2 {
|
||||
t.Errorf("Expected 2 broker, got %d", len(env.Kafka.Brokers))
|
||||
}
|
||||
|
||||
if _, ok := env.Kafka.Encryption.(*envv1.Kafka_TlsEncryption); !ok {
|
||||
t.Errorf("Expected TLS encryption, got %T", env.Kafka.Encryption)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package envfile
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"go.firedancer.io/radiance/proto/env/v1"
|
||||
)
|
||||
|
||||
func ParseOnlyFlag(only string) []string {
|
||||
if only == "" {
|
||||
return nil
|
||||
}
|
||||
return strings.Split(only, ",")
|
||||
}
|
||||
|
||||
func FilterNodes(nodes []*envv1.RPCNode, only []string) []*envv1.RPCNode {
|
||||
if len(only) == 0 {
|
||||
return nodes
|
||||
}
|
||||
var filtered []*envv1.RPCNode
|
||||
for _, node := range nodes {
|
||||
for _, o := range only {
|
||||
if node.Name == o {
|
||||
filtered = append(filtered, node)
|
||||
}
|
||||
}
|
||||
}
|
||||
return filtered
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
nodes {
|
||||
name: "localhost"
|
||||
http: "http://localhost:8899"
|
||||
ws: "ws://localhost:8900"
|
||||
tag: "local"
|
||||
}
|
||||
nodes {
|
||||
name: "localhost_2"
|
||||
http: "http://localhost:8899"
|
||||
ws: "ws://localhost:8900"
|
||||
tag: "local"
|
||||
}
|
||||
|
||||
kafka {
|
||||
brokers: "localhost:9092"
|
||||
brokers: "localhost:9092"
|
||||
topic_prefix: "radiance.dev"
|
||||
|
||||
sasl_auth: {
|
||||
username: "radiance"
|
||||
password: "radiance"
|
||||
}
|
||||
|
||||
tls_encryption: {}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
package kafka
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/twmb/franz-go/pkg/kgo"
|
||||
"github.com/twmb/franz-go/pkg/sasl/scram"
|
||||
envv1 "go.firedancer.io/radiance/proto/env/v1"
|
||||
)
|
||||
|
||||
func NewClientFromEnv(env *envv1.Kafka, opts ...kgo.Opt) (*kgo.Client, error) {
|
||||
opts = append(opts,
|
||||
kgo.SeedBrokers(env.Brokers...),
|
||||
)
|
||||
|
||||
if s, ok := env.Auth.(*envv1.Kafka_SaslAuth); ok {
|
||||
m := scram.Auth{
|
||||
User: s.SaslAuth.Username,
|
||||
Pass: s.SaslAuth.Password}.AsSha256Mechanism()
|
||||
|
||||
opts = append(opts, kgo.SASL(m))
|
||||
}
|
||||
|
||||
if _, ok := env.Encryption.(*envv1.Kafka_TlsEncryption); ok {
|
||||
tlsDialer := &tls.Dialer{NetDialer: &net.Dialer{Timeout: 10 * time.Second}}
|
||||
opts = append(opts, kgo.Dialer(tlsDialer.DialContext))
|
||||
}
|
||||
|
||||
cl, err := kgo.NewClient(opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cl, nil
|
||||
}
|
|
@ -1,220 +0,0 @@
|
|||
package leaderschedule
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gagliardetto/solana-go"
|
||||
"github.com/gagliardetto/solana-go/rpc"
|
||||
envv1 "go.firedancer.io/radiance/proto/env/v1"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
type Tracker struct {
|
||||
// mu guards max and cur
|
||||
mu sync.Mutex
|
||||
// max is the current leader schedule's highest slot
|
||||
max uint64
|
||||
// cur is the current highest slot observed on the network
|
||||
cur uint64
|
||||
|
||||
// bySlot maps slots to their leader. Grows indefinitely as epochs progress.
|
||||
bySlot map[uint64]solana.PublicKey
|
||||
bySlotMu sync.RWMutex
|
||||
|
||||
// slotsPerEpoch is the number of slots per epoch on the network.
|
||||
// Fetched once via RPC. Used to calculate epoch boundaries.
|
||||
slotsPerEpoch uint64
|
||||
|
||||
// initCh is used to signal that the leader schedule is available.
|
||||
initCh chan struct{}
|
||||
|
||||
// c caches RPC client connections by node name.
|
||||
c map[string]*rpc.Client
|
||||
}
|
||||
|
||||
const (
|
||||
// prefetchSlots is the number of slots to prefetch.
|
||||
prefetchSlots = 1000
|
||||
)
|
||||
|
||||
// FirstSlot returns the epoch number and first slot of the epoch.
|
||||
func (t *Tracker) FirstSlot(slotInEpoch uint64) (uint64, uint64) {
|
||||
epoch := slotInEpoch / t.slotsPerEpoch
|
||||
firstSlot := epoch * t.slotsPerEpoch
|
||||
return epoch, firstSlot
|
||||
}
|
||||
|
||||
// Update updates the current highest slot. Non-blocking.
|
||||
func (t *Tracker) Update(slot uint64) {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
|
||||
if slot > t.cur {
|
||||
t.cur = slot
|
||||
}
|
||||
}
|
||||
|
||||
// Run periodically updates the leader schedule. When the current slot + prefetchSlots
|
||||
// is greater than the highest slot in the schedule, the schedule is updated.
|
||||
//
|
||||
// A random node is picked from nodes to do the request against.
|
||||
func (t *Tracker) Run(ctx context.Context, nodes []*envv1.RPCNode) {
|
||||
t.initCh = make(chan struct{})
|
||||
|
||||
t.c = make(map[string]*rpc.Client)
|
||||
for _, node := range nodes {
|
||||
t.c[node.Name] = rpc.New(node.Http)
|
||||
}
|
||||
|
||||
for {
|
||||
// Fetch slots per epoch
|
||||
node := nodes[rand.Intn(len(nodes))]
|
||||
klog.Infof("Fetching epoch schedule from %s", node.Http)
|
||||
out, err := t.c[node.Name].GetEpochSchedule(ctx)
|
||||
if err != nil {
|
||||
klog.Errorf("get epoch schedule: %w", err)
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
if out.FirstNormalEpoch != 0 {
|
||||
panic("first normal epoch should be 0")
|
||||
}
|
||||
if out.FirstNormalSlot != 0 {
|
||||
panic("first normal slot should be 0")
|
||||
}
|
||||
if out.LeaderScheduleSlotOffset <= prefetchSlots {
|
||||
panic("leader schedule slot offset should be greater than prefetch slots")
|
||||
}
|
||||
t.slotsPerEpoch = out.SlotsPerEpoch
|
||||
klog.Infof("Got epoch schedule: slotsPerEpoch=%d", t.slotsPerEpoch)
|
||||
break
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
default:
|
||||
t.mu.Lock()
|
||||
fetch := false
|
||||
|
||||
// If we're less than prefetchSlots slots away from the epoch boundary,
|
||||
// fetch the new leader schedule.
|
||||
threshold := t.cur + prefetchSlots
|
||||
|
||||
if threshold > t.max && t.cur != 0 {
|
||||
fetch = true
|
||||
}
|
||||
|
||||
// If we have no current leader schedule, fetch the current one.
|
||||
var slot uint64
|
||||
var prefetch bool
|
||||
if t.max == 0 {
|
||||
slot = t.cur
|
||||
} else {
|
||||
// If we have a leader schedule, prefetch the next one
|
||||
slot = t.max + 1
|
||||
prefetch = true
|
||||
}
|
||||
t.mu.Unlock()
|
||||
if fetch {
|
||||
if prefetch {
|
||||
klog.Infof("Prefetching leader schedule for cur=%d, threshold=%d, max=%d, slot=%d",
|
||||
t.cur, threshold, t.max, slot)
|
||||
if err := t.fetch(ctx, nodes, slot); err != nil {
|
||||
klog.Errorf("Failed to fetch leader schedule: %v", err)
|
||||
}
|
||||
} else {
|
||||
klog.Infof("Fetching initial leader schedule for cur=%d, threshold=%d, max=%d, slot=%d",
|
||||
t.cur, threshold, t.max, slot)
|
||||
if err := t.fetch(ctx, nodes, slot); err != nil {
|
||||
klog.Errorf("Failed to fetch leader schedule: %v", err)
|
||||
}
|
||||
|
||||
// Signal that the leader schedule is available
|
||||
close(t.initCh)
|
||||
}
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tracker) fetch(ctx context.Context, nodes []*envv1.RPCNode, slot uint64) error {
|
||||
now := time.Now()
|
||||
|
||||
// Pick random node from nodes
|
||||
node := nodes[rand.Intn(len(nodes))]
|
||||
klog.Infof("Using node %s", node.Http)
|
||||
|
||||
// Fetch the leader schedule
|
||||
out, err := t.c[node.Name].GetLeaderScheduleWithOpts(ctx, &rpc.GetLeaderScheduleOpts{
|
||||
Epoch: &slot,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("get leader schedule: %w", err)
|
||||
}
|
||||
|
||||
epoch, firstSlot := t.FirstSlot(slot)
|
||||
|
||||
klog.Infof("Fetched epoch schedule from %s in %v", node.Http, time.Since(now))
|
||||
|
||||
now = time.Now()
|
||||
defer klog.V(1).Infof("bySlotMu: %v", time.Since(now))
|
||||
t.bySlotMu.Lock()
|
||||
defer t.bySlotMu.Unlock()
|
||||
|
||||
if t.bySlot == nil {
|
||||
t.bySlot = make(map[uint64]solana.PublicKey)
|
||||
}
|
||||
|
||||
// Update the leader schedule
|
||||
m := uint64(0)
|
||||
for pk, slots := range out {
|
||||
for _, s := range slots {
|
||||
t.bySlot[firstSlot+s] = pk
|
||||
if firstSlot+s > m {
|
||||
m = firstSlot + s
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t.mu.Lock()
|
||||
t.max = m
|
||||
t.mu.Unlock()
|
||||
|
||||
klog.Infof("Updated leader schedule for epoch=%d, slot=%d, first=%d, max=%d",
|
||||
epoch, slot, firstSlot, t.max)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the scheduled leader for the given slot.
|
||||
// It blocks until the leader schedule is available.
|
||||
func (t *Tracker) Get(slot uint64) solana.PublicKey {
|
||||
// Block until the leader schedule is available
|
||||
if t.initCh != nil {
|
||||
<-t.initCh
|
||||
}
|
||||
|
||||
t.bySlotMu.RLock()
|
||||
defer t.bySlotMu.RUnlock()
|
||||
|
||||
return t.bySlot[slot]
|
||||
}
|
||||
|
||||
// TryGet returns the scheduled leader for the given slot.
|
||||
// It returns false if the leader schedule is not yet available.
|
||||
func (t *Tracker) TryGet(slot uint64) (solana.PublicKey, bool) {
|
||||
t.bySlotMu.RLock()
|
||||
defer t.bySlotMu.RUnlock()
|
||||
|
||||
if t.bySlot == nil {
|
||||
return solana.PublicKey{}, false
|
||||
}
|
||||
|
||||
return t.bySlot[slot], true
|
||||
}
|
|
@ -1,595 +0,0 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.17.3
|
||||
// source: proto/env/v1/env.proto
|
||||
|
||||
package envv1
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type Env struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Nodes []*RPCNode `protobuf:"bytes,1,rep,name=nodes,proto3" json:"nodes,omitempty"`
|
||||
Kafka *Kafka `protobuf:"bytes,2,opt,name=kafka,proto3" json:"kafka,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Env) Reset() {
|
||||
*x = Env{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_env_v1_env_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Env) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Env) ProtoMessage() {}
|
||||
|
||||
func (x *Env) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_env_v1_env_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Env.ProtoReflect.Descriptor instead.
|
||||
func (*Env) Descriptor() ([]byte, []int) {
|
||||
return file_proto_env_v1_env_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Env) GetNodes() []*RPCNode {
|
||||
if x != nil {
|
||||
return x.Nodes
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Env) GetKafka() *Kafka {
|
||||
if x != nil {
|
||||
return x.Kafka
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type RPCNode struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Http string `protobuf:"bytes,2,opt,name=http,proto3" json:"http,omitempty"`
|
||||
Ws string `protobuf:"bytes,3,opt,name=ws,proto3" json:"ws,omitempty"`
|
||||
Tag []string `protobuf:"bytes,4,rep,name=tag,proto3" json:"tag,omitempty"`
|
||||
}
|
||||
|
||||
func (x *RPCNode) Reset() {
|
||||
*x = RPCNode{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_env_v1_env_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *RPCNode) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RPCNode) ProtoMessage() {}
|
||||
|
||||
func (x *RPCNode) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_env_v1_env_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RPCNode.ProtoReflect.Descriptor instead.
|
||||
func (*RPCNode) Descriptor() ([]byte, []int) {
|
||||
return file_proto_env_v1_env_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *RPCNode) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *RPCNode) GetHttp() string {
|
||||
if x != nil {
|
||||
return x.Http
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *RPCNode) GetWs() string {
|
||||
if x != nil {
|
||||
return x.Ws
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *RPCNode) GetTag() []string {
|
||||
if x != nil {
|
||||
return x.Tag
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Kafka struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// List of seed brokers.
|
||||
Brokers []string `protobuf:"bytes,1,rep,name=brokers,proto3" json:"brokers,omitempty"`
|
||||
// Topic prefix (dot notation). The topic name is the prefix + application-specific name.
|
||||
TopicPrefix string `protobuf:"bytes,2,opt,name=topic_prefix,json=topicPrefix,proto3" json:"topic_prefix,omitempty"`
|
||||
// Authentication method.
|
||||
//
|
||||
// Types that are assignable to Auth:
|
||||
// *Kafka_NoAuth
|
||||
// *Kafka_SaslAuth
|
||||
Auth isKafka_Auth `protobuf_oneof:"auth"`
|
||||
// Encryption
|
||||
//
|
||||
// Types that are assignable to Encryption:
|
||||
// *Kafka_TlsEncryption
|
||||
Encryption isKafka_Encryption `protobuf_oneof:"encryption"`
|
||||
}
|
||||
|
||||
func (x *Kafka) Reset() {
|
||||
*x = Kafka{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_env_v1_env_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Kafka) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Kafka) ProtoMessage() {}
|
||||
|
||||
func (x *Kafka) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_env_v1_env_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Kafka.ProtoReflect.Descriptor instead.
|
||||
func (*Kafka) Descriptor() ([]byte, []int) {
|
||||
return file_proto_env_v1_env_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *Kafka) GetBrokers() []string {
|
||||
if x != nil {
|
||||
return x.Brokers
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Kafka) GetTopicPrefix() string {
|
||||
if x != nil {
|
||||
return x.TopicPrefix
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Kafka) GetAuth() isKafka_Auth {
|
||||
if m != nil {
|
||||
return m.Auth
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Kafka) GetNoAuth() *Kafka_KafkaNoAuth {
|
||||
if x, ok := x.GetAuth().(*Kafka_NoAuth); ok {
|
||||
return x.NoAuth
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Kafka) GetSaslAuth() *Kafka_KafkaSASLAuth {
|
||||
if x, ok := x.GetAuth().(*Kafka_SaslAuth); ok {
|
||||
return x.SaslAuth
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Kafka) GetEncryption() isKafka_Encryption {
|
||||
if m != nil {
|
||||
return m.Encryption
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Kafka) GetTlsEncryption() *Kafka_KafkaTLSEncryption {
|
||||
if x, ok := x.GetEncryption().(*Kafka_TlsEncryption); ok {
|
||||
return x.TlsEncryption
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type isKafka_Auth interface {
|
||||
isKafka_Auth()
|
||||
}
|
||||
|
||||
type Kafka_NoAuth struct {
|
||||
// No authentication.
|
||||
NoAuth *Kafka_KafkaNoAuth `protobuf:"bytes,3,opt,name=no_auth,json=noAuth,proto3,oneof"`
|
||||
}
|
||||
|
||||
type Kafka_SaslAuth struct {
|
||||
// SASL authentication.
|
||||
SaslAuth *Kafka_KafkaSASLAuth `protobuf:"bytes,4,opt,name=sasl_auth,json=saslAuth,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*Kafka_NoAuth) isKafka_Auth() {}
|
||||
|
||||
func (*Kafka_SaslAuth) isKafka_Auth() {}
|
||||
|
||||
type isKafka_Encryption interface {
|
||||
isKafka_Encryption()
|
||||
}
|
||||
|
||||
type Kafka_TlsEncryption struct {
|
||||
// TLS encryption.
|
||||
TlsEncryption *Kafka_KafkaTLSEncryption `protobuf:"bytes,6,opt,name=tls_encryption,json=tlsEncryption,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*Kafka_TlsEncryption) isKafka_Encryption() {}
|
||||
|
||||
// SASL SCRAM-SHA-256 authentication.
|
||||
type Kafka_KafkaSASLAuth struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"`
|
||||
Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Kafka_KafkaSASLAuth) Reset() {
|
||||
*x = Kafka_KafkaSASLAuth{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_env_v1_env_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Kafka_KafkaSASLAuth) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Kafka_KafkaSASLAuth) ProtoMessage() {}
|
||||
|
||||
func (x *Kafka_KafkaSASLAuth) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_env_v1_env_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Kafka_KafkaSASLAuth.ProtoReflect.Descriptor instead.
|
||||
func (*Kafka_KafkaSASLAuth) Descriptor() ([]byte, []int) {
|
||||
return file_proto_env_v1_env_proto_rawDescGZIP(), []int{2, 0}
|
||||
}
|
||||
|
||||
func (x *Kafka_KafkaSASLAuth) GetUsername() string {
|
||||
if x != nil {
|
||||
return x.Username
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Kafka_KafkaSASLAuth) GetPassword() string {
|
||||
if x != nil {
|
||||
return x.Password
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Kafka_KafkaNoAuth struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *Kafka_KafkaNoAuth) Reset() {
|
||||
*x = Kafka_KafkaNoAuth{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_env_v1_env_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Kafka_KafkaNoAuth) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Kafka_KafkaNoAuth) ProtoMessage() {}
|
||||
|
||||
func (x *Kafka_KafkaNoAuth) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_env_v1_env_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Kafka_KafkaNoAuth.ProtoReflect.Descriptor instead.
|
||||
func (*Kafka_KafkaNoAuth) Descriptor() ([]byte, []int) {
|
||||
return file_proto_env_v1_env_proto_rawDescGZIP(), []int{2, 1}
|
||||
}
|
||||
|
||||
// TLS encryption.
|
||||
type Kafka_KafkaTLSEncryption struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *Kafka_KafkaTLSEncryption) Reset() {
|
||||
*x = Kafka_KafkaTLSEncryption{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_env_v1_env_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Kafka_KafkaTLSEncryption) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Kafka_KafkaTLSEncryption) ProtoMessage() {}
|
||||
|
||||
func (x *Kafka_KafkaTLSEncryption) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_env_v1_env_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Kafka_KafkaTLSEncryption.ProtoReflect.Descriptor instead.
|
||||
func (*Kafka_KafkaTLSEncryption) Descriptor() ([]byte, []int) {
|
||||
return file_proto_env_v1_env_proto_rawDescGZIP(), []int{2, 2}
|
||||
}
|
||||
|
||||
var File_proto_env_v1_env_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_proto_env_v1_env_proto_rawDesc = []byte{
|
||||
0x0a, 0x16, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x6e, 0x76, 0x2f, 0x76, 0x31, 0x2f, 0x65,
|
||||
0x6e, 0x76, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x65, 0x6e, 0x76, 0x22, 0x4b, 0x0a,
|
||||
0x03, 0x45, 0x6e, 0x76, 0x12, 0x22, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x65, 0x6e, 0x76, 0x2e, 0x52, 0x50, 0x43, 0x4e, 0x6f, 0x64,
|
||||
0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x05, 0x6b, 0x61, 0x66, 0x6b,
|
||||
0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x65, 0x6e, 0x76, 0x2e, 0x4b, 0x61,
|
||||
0x66, 0x6b, 0x61, 0x52, 0x05, 0x6b, 0x61, 0x66, 0x6b, 0x61, 0x22, 0x53, 0x0a, 0x07, 0x52, 0x50,
|
||||
0x43, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x74, 0x74,
|
||||
0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x74, 0x74, 0x70, 0x12, 0x0e, 0x0a,
|
||||
0x02, 0x77, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x77, 0x73, 0x12, 0x10, 0x0a,
|
||||
0x03, 0x74, 0x61, 0x67, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x22,
|
||||
0xfc, 0x02, 0x0a, 0x05, 0x4b, 0x61, 0x66, 0x6b, 0x61, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x72, 0x6f,
|
||||
0x6b, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x62, 0x72, 0x6f, 0x6b,
|
||||
0x65, 0x72, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x5f, 0x70, 0x72, 0x65,
|
||||
0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x6f, 0x70, 0x69, 0x63,
|
||||
0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x31, 0x0a, 0x07, 0x6e, 0x6f, 0x5f, 0x61, 0x75, 0x74,
|
||||
0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x65, 0x6e, 0x76, 0x2e, 0x4b, 0x61,
|
||||
0x66, 0x6b, 0x61, 0x2e, 0x4b, 0x61, 0x66, 0x6b, 0x61, 0x4e, 0x6f, 0x41, 0x75, 0x74, 0x68, 0x48,
|
||||
0x00, 0x52, 0x06, 0x6e, 0x6f, 0x41, 0x75, 0x74, 0x68, 0x12, 0x37, 0x0a, 0x09, 0x73, 0x61, 0x73,
|
||||
0x6c, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x65,
|
||||
0x6e, 0x76, 0x2e, 0x4b, 0x61, 0x66, 0x6b, 0x61, 0x2e, 0x4b, 0x61, 0x66, 0x6b, 0x61, 0x53, 0x41,
|
||||
0x53, 0x4c, 0x41, 0x75, 0x74, 0x68, 0x48, 0x00, 0x52, 0x08, 0x73, 0x61, 0x73, 0x6c, 0x41, 0x75,
|
||||
0x74, 0x68, 0x12, 0x46, 0x0a, 0x0e, 0x74, 0x6c, 0x73, 0x5f, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x65, 0x6e, 0x76,
|
||||
0x2e, 0x4b, 0x61, 0x66, 0x6b, 0x61, 0x2e, 0x4b, 0x61, 0x66, 0x6b, 0x61, 0x54, 0x4c, 0x53, 0x45,
|
||||
0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x01, 0x52, 0x0d, 0x74, 0x6c, 0x73,
|
||||
0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x47, 0x0a, 0x0d, 0x4b, 0x61,
|
||||
0x66, 0x6b, 0x61, 0x53, 0x41, 0x53, 0x4c, 0x41, 0x75, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x75,
|
||||
0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75,
|
||||
0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77,
|
||||
0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77,
|
||||
0x6f, 0x72, 0x64, 0x1a, 0x0d, 0x0a, 0x0b, 0x4b, 0x61, 0x66, 0x6b, 0x61, 0x4e, 0x6f, 0x41, 0x75,
|
||||
0x74, 0x68, 0x1a, 0x14, 0x0a, 0x12, 0x4b, 0x61, 0x66, 0x6b, 0x61, 0x54, 0x4c, 0x53, 0x45, 0x6e,
|
||||
0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x06, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68,
|
||||
0x42, 0x0c, 0x0a, 0x0a, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x2d,
|
||||
0x5a, 0x2b, 0x67, 0x6f, 0x2e, 0x66, 0x69, 0x72, 0x65, 0x64, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e,
|
||||
0x69, 0x6f, 0x2f, 0x72, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x2f, 0x65, 0x6e, 0x76, 0x76, 0x31, 0x3b, 0x65, 0x6e, 0x76, 0x76, 0x31, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_proto_env_v1_env_proto_rawDescOnce sync.Once
|
||||
file_proto_env_v1_env_proto_rawDescData = file_proto_env_v1_env_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_proto_env_v1_env_proto_rawDescGZIP() []byte {
|
||||
file_proto_env_v1_env_proto_rawDescOnce.Do(func() {
|
||||
file_proto_env_v1_env_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_env_v1_env_proto_rawDescData)
|
||||
})
|
||||
return file_proto_env_v1_env_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_proto_env_v1_env_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
||||
var file_proto_env_v1_env_proto_goTypes = []interface{}{
|
||||
(*Env)(nil), // 0: env.Env
|
||||
(*RPCNode)(nil), // 1: env.RPCNode
|
||||
(*Kafka)(nil), // 2: env.Kafka
|
||||
(*Kafka_KafkaSASLAuth)(nil), // 3: env.Kafka.KafkaSASLAuth
|
||||
(*Kafka_KafkaNoAuth)(nil), // 4: env.Kafka.KafkaNoAuth
|
||||
(*Kafka_KafkaTLSEncryption)(nil), // 5: env.Kafka.KafkaTLSEncryption
|
||||
}
|
||||
var file_proto_env_v1_env_proto_depIdxs = []int32{
|
||||
1, // 0: env.Env.nodes:type_name -> env.RPCNode
|
||||
2, // 1: env.Env.kafka:type_name -> env.Kafka
|
||||
4, // 2: env.Kafka.no_auth:type_name -> env.Kafka.KafkaNoAuth
|
||||
3, // 3: env.Kafka.sasl_auth:type_name -> env.Kafka.KafkaSASLAuth
|
||||
5, // 4: env.Kafka.tls_encryption:type_name -> env.Kafka.KafkaTLSEncryption
|
||||
5, // [5:5] is the sub-list for method output_type
|
||||
5, // [5:5] is the sub-list for method input_type
|
||||
5, // [5:5] is the sub-list for extension type_name
|
||||
5, // [5:5] is the sub-list for extension extendee
|
||||
0, // [0:5] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_proto_env_v1_env_proto_init() }
|
||||
func file_proto_env_v1_env_proto_init() {
|
||||
if File_proto_env_v1_env_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_proto_env_v1_env_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Env); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_env_v1_env_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RPCNode); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_env_v1_env_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Kafka); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_env_v1_env_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Kafka_KafkaSASLAuth); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_env_v1_env_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Kafka_KafkaNoAuth); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_env_v1_env_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Kafka_KafkaTLSEncryption); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
file_proto_env_v1_env_proto_msgTypes[2].OneofWrappers = []interface{}{
|
||||
(*Kafka_NoAuth)(nil),
|
||||
(*Kafka_SaslAuth)(nil),
|
||||
(*Kafka_TlsEncryption)(nil),
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_proto_env_v1_env_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 6,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_proto_env_v1_env_proto_goTypes,
|
||||
DependencyIndexes: file_proto_env_v1_env_proto_depIdxs,
|
||||
MessageInfos: file_proto_env_v1_env_proto_msgTypes,
|
||||
}.Build()
|
||||
File_proto_env_v1_env_proto = out.File
|
||||
file_proto_env_v1_env_proto_rawDesc = nil
|
||||
file_proto_env_v1_env_proto_goTypes = nil
|
||||
file_proto_env_v1_env_proto_depIdxs = nil
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package env;
|
||||
|
||||
option go_package = "go.firedancer.io/radiance/proto/envv1;envv1";
|
||||
|
||||
// Package env provides shared environment configuration values.
|
||||
|
||||
message Env {
|
||||
repeated RPCNode nodes = 1;
|
||||
Kafka kafka = 2;
|
||||
}
|
||||
|
||||
message RPCNode {
|
||||
string name = 1;
|
||||
string http = 2;
|
||||
string ws = 3;
|
||||
repeated string tag = 4;
|
||||
}
|
||||
|
||||
message Kafka {
|
||||
// List of seed brokers.
|
||||
repeated string brokers = 1;
|
||||
// Topic prefix (dot notation). The topic name is the prefix + application-specific name.
|
||||
string topic_prefix = 2;
|
||||
|
||||
// SASL SCRAM-SHA-256 authentication.
|
||||
message KafkaSASLAuth {
|
||||
string username = 1;
|
||||
string password = 2;
|
||||
}
|
||||
|
||||
message KafkaNoAuth{}
|
||||
|
||||
// Authentication method.
|
||||
oneof auth {
|
||||
// No authentication.
|
||||
KafkaNoAuth no_auth = 3;
|
||||
// SASL authentication.
|
||||
KafkaSASLAuth sasl_auth = 4;
|
||||
}
|
||||
|
||||
// Encryption
|
||||
oneof encryption {
|
||||
// TLS encryption.
|
||||
KafkaTLSEncryption tls_encryption = 6;
|
||||
}
|
||||
|
||||
// TLS encryption.
|
||||
message KafkaTLSEncryption {}
|
||||
}
|
||||
|
|
@ -1,405 +0,0 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.17.3
|
||||
// source: proto/heimdall/v1/heimdall.proto
|
||||
|
||||
package heimdallv1
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type Observation struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
BankSlot uint64 `protobuf:"varint,1,opt,name=bankSlot,proto3" json:"bankSlot,omitempty"`
|
||||
BankID uint64 `protobuf:"varint,2,opt,name=bankID,proto3" json:"bankID,omitempty"`
|
||||
BankParentHash string `protobuf:"bytes,3,opt,name=bankParentHash,proto3" json:"bankParentHash,omitempty"`
|
||||
FeePayer string `protobuf:"bytes,4,opt,name=feePayer,proto3" json:"feePayer,omitempty"`
|
||||
Signature string `protobuf:"bytes,5,opt,name=signature,proto3" json:"signature,omitempty"`
|
||||
Program string `protobuf:"bytes,6,opt,name=program,proto3" json:"program,omitempty"`
|
||||
Timings *Timings `protobuf:"bytes,7,opt,name=timings,proto3" json:"timings,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Observation) Reset() {
|
||||
*x = Observation{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_heimdall_v1_heimdall_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Observation) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Observation) ProtoMessage() {}
|
||||
|
||||
func (x *Observation) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_heimdall_v1_heimdall_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Observation.ProtoReflect.Descriptor instead.
|
||||
func (*Observation) Descriptor() ([]byte, []int) {
|
||||
return file_proto_heimdall_v1_heimdall_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Observation) GetBankSlot() uint64 {
|
||||
if x != nil {
|
||||
return x.BankSlot
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Observation) GetBankID() uint64 {
|
||||
if x != nil {
|
||||
return x.BankID
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Observation) GetBankParentHash() string {
|
||||
if x != nil {
|
||||
return x.BankParentHash
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Observation) GetFeePayer() string {
|
||||
if x != nil {
|
||||
return x.FeePayer
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Observation) GetSignature() string {
|
||||
if x != nil {
|
||||
return x.Signature
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Observation) GetProgram() string {
|
||||
if x != nil {
|
||||
return x.Program
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Observation) GetTimings() *Timings {
|
||||
if x != nil {
|
||||
return x.Timings
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Timings struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
SerializeUs uint64 `protobuf:"varint,1,opt,name=serialize_us,json=serializeUs,proto3" json:"serialize_us,omitempty"`
|
||||
CreateVmUs uint64 `protobuf:"varint,2,opt,name=create_vm_us,json=createVmUs,proto3" json:"create_vm_us,omitempty"`
|
||||
ExecuteUs uint64 `protobuf:"varint,3,opt,name=execute_us,json=executeUs,proto3" json:"execute_us,omitempty"`
|
||||
DeserializeUs uint64 `protobuf:"varint,4,opt,name=deserialize_us,json=deserializeUs,proto3" json:"deserialize_us,omitempty"`
|
||||
GetOrCreateExecutorUs uint64 `protobuf:"varint,5,opt,name=get_or_create_executor_us,json=getOrCreateExecutorUs,proto3" json:"get_or_create_executor_us,omitempty"`
|
||||
ChangedAccountCount uint64 `protobuf:"varint,6,opt,name=changed_account_count,json=changedAccountCount,proto3" json:"changed_account_count,omitempty"`
|
||||
TotalAccountCount uint64 `protobuf:"varint,7,opt,name=total_account_count,json=totalAccountCount,proto3" json:"total_account_count,omitempty"`
|
||||
TotalDataSize uint64 `protobuf:"varint,8,opt,name=total_data_size,json=totalDataSize,proto3" json:"total_data_size,omitempty"`
|
||||
DataSizeChanged uint64 `protobuf:"varint,9,opt,name=data_size_changed,json=dataSizeChanged,proto3" json:"data_size_changed,omitempty"`
|
||||
CreateExecutorRegisterSyscallsUs uint64 `protobuf:"varint,10,opt,name=create_executor_register_syscalls_us,json=createExecutorRegisterSyscallsUs,proto3" json:"create_executor_register_syscalls_us,omitempty"`
|
||||
CreateExecutorLoadElfUs uint64 `protobuf:"varint,11,opt,name=create_executor_load_elf_us,json=createExecutorLoadElfUs,proto3" json:"create_executor_load_elf_us,omitempty"`
|
||||
CreateExecutorVerifyCodeUs uint64 `protobuf:"varint,12,opt,name=create_executor_verify_code_us,json=createExecutorVerifyCodeUs,proto3" json:"create_executor_verify_code_us,omitempty"`
|
||||
CreateExecutorJitCompileUs uint64 `protobuf:"varint,13,opt,name=create_executor_jit_compile_us,json=createExecutorJitCompileUs,proto3" json:"create_executor_jit_compile_us,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Timings) Reset() {
|
||||
*x = Timings{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_heimdall_v1_heimdall_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Timings) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Timings) ProtoMessage() {}
|
||||
|
||||
func (x *Timings) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_heimdall_v1_heimdall_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Timings.ProtoReflect.Descriptor instead.
|
||||
func (*Timings) Descriptor() ([]byte, []int) {
|
||||
return file_proto_heimdall_v1_heimdall_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *Timings) GetSerializeUs() uint64 {
|
||||
if x != nil {
|
||||
return x.SerializeUs
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Timings) GetCreateVmUs() uint64 {
|
||||
if x != nil {
|
||||
return x.CreateVmUs
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Timings) GetExecuteUs() uint64 {
|
||||
if x != nil {
|
||||
return x.ExecuteUs
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Timings) GetDeserializeUs() uint64 {
|
||||
if x != nil {
|
||||
return x.DeserializeUs
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Timings) GetGetOrCreateExecutorUs() uint64 {
|
||||
if x != nil {
|
||||
return x.GetOrCreateExecutorUs
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Timings) GetChangedAccountCount() uint64 {
|
||||
if x != nil {
|
||||
return x.ChangedAccountCount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Timings) GetTotalAccountCount() uint64 {
|
||||
if x != nil {
|
||||
return x.TotalAccountCount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Timings) GetTotalDataSize() uint64 {
|
||||
if x != nil {
|
||||
return x.TotalDataSize
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Timings) GetDataSizeChanged() uint64 {
|
||||
if x != nil {
|
||||
return x.DataSizeChanged
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Timings) GetCreateExecutorRegisterSyscallsUs() uint64 {
|
||||
if x != nil {
|
||||
return x.CreateExecutorRegisterSyscallsUs
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Timings) GetCreateExecutorLoadElfUs() uint64 {
|
||||
if x != nil {
|
||||
return x.CreateExecutorLoadElfUs
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Timings) GetCreateExecutorVerifyCodeUs() uint64 {
|
||||
if x != nil {
|
||||
return x.CreateExecutorVerifyCodeUs
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Timings) GetCreateExecutorJitCompileUs() uint64 {
|
||||
if x != nil {
|
||||
return x.CreateExecutorJitCompileUs
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var File_proto_heimdall_v1_heimdall_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_proto_heimdall_v1_heimdall_proto_rawDesc = []byte{
|
||||
0x0a, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x68, 0x65, 0x69, 0x6d, 0x64, 0x61, 0x6c, 0x6c,
|
||||
0x2f, 0x76, 0x31, 0x2f, 0x68, 0x65, 0x69, 0x6d, 0x64, 0x61, 0x6c, 0x6c, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x12, 0x08, 0x68, 0x65, 0x69, 0x6d, 0x64, 0x61, 0x6c, 0x6c, 0x22, 0xea, 0x01, 0x0a,
|
||||
0x0b, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08,
|
||||
0x62, 0x61, 0x6e, 0x6b, 0x53, 0x6c, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08,
|
||||
0x62, 0x61, 0x6e, 0x6b, 0x53, 0x6c, 0x6f, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x61, 0x6e, 0x6b,
|
||||
0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x62, 0x61, 0x6e, 0x6b, 0x49, 0x44,
|
||||
0x12, 0x26, 0x0a, 0x0e, 0x62, 0x61, 0x6e, 0x6b, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x61,
|
||||
0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x62, 0x61, 0x6e, 0x6b, 0x50, 0x61,
|
||||
0x72, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x65, 0x65, 0x50,
|
||||
0x61, 0x79, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x65, 0x65, 0x50,
|
||||
0x61, 0x79, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72,
|
||||
0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75,
|
||||
0x72, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x18, 0x06, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x12, 0x2b, 0x0a, 0x07,
|
||||
0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e,
|
||||
0x68, 0x65, 0x69, 0x6d, 0x64, 0x61, 0x6c, 0x6c, 0x2e, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x73,
|
||||
0x52, 0x07, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x9c, 0x05, 0x0a, 0x07, 0x54, 0x69,
|
||||
0x6d, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69,
|
||||
0x7a, 0x65, 0x5f, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x73, 0x65, 0x72,
|
||||
0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x55, 0x73, 0x12, 0x20, 0x0a, 0x0c, 0x63, 0x72, 0x65, 0x61,
|
||||
0x74, 0x65, 0x5f, 0x76, 0x6d, 0x5f, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a,
|
||||
0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x6d, 0x55, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x78,
|
||||
0x65, 0x63, 0x75, 0x74, 0x65, 0x5f, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09,
|
||||
0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x55, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x65, 0x73,
|
||||
0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x5f, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x04, 0x52, 0x0d, 0x64, 0x65, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x55, 0x73,
|
||||
0x12, 0x38, 0x0a, 0x19, 0x67, 0x65, 0x74, 0x5f, 0x6f, 0x72, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74,
|
||||
0x65, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x5f, 0x75, 0x73, 0x18, 0x05, 0x20,
|
||||
0x01, 0x28, 0x04, 0x52, 0x15, 0x67, 0x65, 0x74, 0x4f, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
|
||||
0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x55, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x63, 0x68,
|
||||
0x61, 0x6e, 0x67, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x63, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x63, 0x68, 0x61, 0x6e, 0x67,
|
||||
0x65, 0x64, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2e,
|
||||
0x0a, 0x13, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x74, 0x6f, 0x74,
|
||||
0x61, 0x6c, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x26,
|
||||
0x0a, 0x0f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x69, 0x7a,
|
||||
0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x44, 0x61,
|
||||
0x74, 0x61, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73,
|
||||
0x69, 0x7a, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28,
|
||||
0x04, 0x52, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x53, 0x69, 0x7a, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67,
|
||||
0x65, 0x64, 0x12, 0x4e, 0x0a, 0x24, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x78, 0x65,
|
||||
0x63, 0x75, 0x74, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x73,
|
||||
0x79, 0x73, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x5f, 0x75, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04,
|
||||
0x52, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72,
|
||||
0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, 0x79, 0x73, 0x63, 0x61, 0x6c, 0x6c, 0x73,
|
||||
0x55, 0x73, 0x12, 0x3c, 0x0a, 0x1b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x78, 0x65,
|
||||
0x63, 0x75, 0x74, 0x6f, 0x72, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x65, 0x6c, 0x66, 0x5f, 0x75,
|
||||
0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x17, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45,
|
||||
0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x4c, 0x6f, 0x61, 0x64, 0x45, 0x6c, 0x66, 0x55, 0x73,
|
||||
0x12, 0x42, 0x0a, 0x1e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x75,
|
||||
0x74, 0x6f, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x5f,
|
||||
0x75, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65,
|
||||
0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x6f,
|
||||
0x64, 0x65, 0x55, 0x73, 0x12, 0x42, 0x0a, 0x1e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x65,
|
||||
0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x5f, 0x6a, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x70,
|
||||
0x69, 0x6c, 0x65, 0x5f, 0x75, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1a, 0x63, 0x72,
|
||||
0x65, 0x61, 0x74, 0x65, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x4a, 0x69, 0x74, 0x43,
|
||||
0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x55, 0x73, 0x42, 0x35, 0x5a, 0x33, 0x67, 0x6f, 0x2e, 0x66,
|
||||
0x69, 0x72, 0x65, 0x64, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x69, 0x6f, 0x2f, 0x72, 0x61, 0x64,
|
||||
0x69, 0x61, 0x6e, 0x63, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x68, 0x65, 0x69, 0x6d,
|
||||
0x64, 0x61, 0x6c, 0x6c, 0x3b, 0x68, 0x65, 0x69, 0x6d, 0x64, 0x61, 0x6c, 0x6c, 0x76, 0x31, 0x62,
|
||||
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_proto_heimdall_v1_heimdall_proto_rawDescOnce sync.Once
|
||||
file_proto_heimdall_v1_heimdall_proto_rawDescData = file_proto_heimdall_v1_heimdall_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_proto_heimdall_v1_heimdall_proto_rawDescGZIP() []byte {
|
||||
file_proto_heimdall_v1_heimdall_proto_rawDescOnce.Do(func() {
|
||||
file_proto_heimdall_v1_heimdall_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_heimdall_v1_heimdall_proto_rawDescData)
|
||||
})
|
||||
return file_proto_heimdall_v1_heimdall_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_proto_heimdall_v1_heimdall_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_proto_heimdall_v1_heimdall_proto_goTypes = []interface{}{
|
||||
(*Observation)(nil), // 0: heimdall.Observation
|
||||
(*Timings)(nil), // 1: heimdall.Timings
|
||||
}
|
||||
var file_proto_heimdall_v1_heimdall_proto_depIdxs = []int32{
|
||||
1, // 0: heimdall.Observation.timings:type_name -> heimdall.Timings
|
||||
1, // [1:1] is the sub-list for method output_type
|
||||
1, // [1:1] is the sub-list for method input_type
|
||||
1, // [1:1] is the sub-list for extension type_name
|
||||
1, // [1:1] is the sub-list for extension extendee
|
||||
0, // [0:1] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_proto_heimdall_v1_heimdall_proto_init() }
|
||||
func file_proto_heimdall_v1_heimdall_proto_init() {
|
||||
if File_proto_heimdall_v1_heimdall_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_proto_heimdall_v1_heimdall_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Observation); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_heimdall_v1_heimdall_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Timings); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_proto_heimdall_v1_heimdall_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_proto_heimdall_v1_heimdall_proto_goTypes,
|
||||
DependencyIndexes: file_proto_heimdall_v1_heimdall_proto_depIdxs,
|
||||
MessageInfos: file_proto_heimdall_v1_heimdall_proto_msgTypes,
|
||||
}.Build()
|
||||
File_proto_heimdall_v1_heimdall_proto = out.File
|
||||
file_proto_heimdall_v1_heimdall_proto_rawDesc = nil
|
||||
file_proto_heimdall_v1_heimdall_proto_goTypes = nil
|
||||
file_proto_heimdall_v1_heimdall_proto_depIdxs = nil
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package heimdall;
|
||||
|
||||
option go_package = "go.firedancer.io/radiance/proto/heimdall;heimdallv1";
|
||||
|
||||
message Observation{
|
||||
uint64 bankSlot = 1;
|
||||
uint64 bankID = 2;
|
||||
string bankParentHash = 3;
|
||||
string feePayer = 4;
|
||||
string signature = 5;
|
||||
string program = 6;
|
||||
Timings timings = 7;
|
||||
}
|
||||
|
||||
message Timings {
|
||||
uint64 serialize_us = 1;
|
||||
uint64 create_vm_us = 2;
|
||||
uint64 execute_us = 3;
|
||||
uint64 deserialize_us = 4;
|
||||
uint64 get_or_create_executor_us = 5;
|
||||
uint64 changed_account_count = 6;
|
||||
uint64 total_account_count = 7;
|
||||
uint64 total_data_size = 8;
|
||||
uint64 data_size_changed = 9;
|
||||
uint64 create_executor_register_syscalls_us = 10;
|
||||
uint64 create_executor_load_elf_us = 11;
|
||||
uint64 create_executor_verify_code_us = 12;
|
||||
uint64 create_executor_jit_compile_us = 13;
|
||||
}
|
|
@ -1,422 +0,0 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.17.3
|
||||
// source: proto/network/v1/slot_status.proto
|
||||
|
||||
package networkv1
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// Update type
|
||||
type SlotStatus_UpdateType int32
|
||||
|
||||
const (
|
||||
SlotStatus_UPDATE_TYPE_UNSPECIFIED SlotStatus_UpdateType = 0
|
||||
SlotStatus_UPDATE_TYPE_FIRST_SHRED_RECEIVED SlotStatus_UpdateType = 1
|
||||
SlotStatus_UPDATE_TYPE_COMPLETED SlotStatus_UpdateType = 2
|
||||
SlotStatus_UPDATE_TYPE_CREATED_BANK SlotStatus_UpdateType = 3
|
||||
SlotStatus_UPDATE_TYPE_FROZEN SlotStatus_UpdateType = 4
|
||||
SlotStatus_UPDATE_TYPE_DEAD SlotStatus_UpdateType = 5
|
||||
SlotStatus_UPDATE_TYPE_OPTIMISTIC_CONFIRMATION SlotStatus_UpdateType = 6
|
||||
SlotStatus_UPDATE_TYPE_ROOT SlotStatus_UpdateType = 7
|
||||
)
|
||||
|
||||
// Enum value maps for SlotStatus_UpdateType.
|
||||
var (
|
||||
SlotStatus_UpdateType_name = map[int32]string{
|
||||
0: "UPDATE_TYPE_UNSPECIFIED",
|
||||
1: "UPDATE_TYPE_FIRST_SHRED_RECEIVED",
|
||||
2: "UPDATE_TYPE_COMPLETED",
|
||||
3: "UPDATE_TYPE_CREATED_BANK",
|
||||
4: "UPDATE_TYPE_FROZEN",
|
||||
5: "UPDATE_TYPE_DEAD",
|
||||
6: "UPDATE_TYPE_OPTIMISTIC_CONFIRMATION",
|
||||
7: "UPDATE_TYPE_ROOT",
|
||||
}
|
||||
SlotStatus_UpdateType_value = map[string]int32{
|
||||
"UPDATE_TYPE_UNSPECIFIED": 0,
|
||||
"UPDATE_TYPE_FIRST_SHRED_RECEIVED": 1,
|
||||
"UPDATE_TYPE_COMPLETED": 2,
|
||||
"UPDATE_TYPE_CREATED_BANK": 3,
|
||||
"UPDATE_TYPE_FROZEN": 4,
|
||||
"UPDATE_TYPE_DEAD": 5,
|
||||
"UPDATE_TYPE_OPTIMISTIC_CONFIRMATION": 6,
|
||||
"UPDATE_TYPE_ROOT": 7,
|
||||
}
|
||||
)
|
||||
|
||||
func (x SlotStatus_UpdateType) Enum() *SlotStatus_UpdateType {
|
||||
p := new(SlotStatus_UpdateType)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x SlotStatus_UpdateType) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (SlotStatus_UpdateType) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_proto_network_v1_slot_status_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (SlotStatus_UpdateType) Type() protoreflect.EnumType {
|
||||
return &file_proto_network_v1_slot_status_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x SlotStatus_UpdateType) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use SlotStatus_UpdateType.Descriptor instead.
|
||||
func (SlotStatus_UpdateType) EnumDescriptor() ([]byte, []int) {
|
||||
return file_proto_network_v1_slot_status_proto_rawDescGZIP(), []int{0, 0}
|
||||
}
|
||||
|
||||
// See client/src/rpc_response.rs.
|
||||
type SlotStatus struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// Slot number
|
||||
Slot uint64 `protobuf:"varint,1,opt,name=slot,proto3" json:"slot,omitempty"`
|
||||
// Millisecond UNIX timestamp of the observation on the Solana node.
|
||||
// Depends on accurate local clocks.
|
||||
Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
|
||||
// One-way delay between the Solana node and the client.
|
||||
Delay uint64 `protobuf:"varint,3,opt,name=delay,proto3" json:"delay,omitempty"`
|
||||
Type SlotStatus_UpdateType `protobuf:"varint,4,opt,name=type,proto3,enum=proto.network.v1.SlotStatus_UpdateType" json:"type,omitempty"`
|
||||
// For type == CREATED_BANK, the parent slot number is included.
|
||||
Parent uint64 `protobuf:"varint,5,opt,name=parent,proto3" json:"parent,omitempty"`
|
||||
// For type == FROZEN, extra transaction stats are included.
|
||||
Stats *TxStats `protobuf:"bytes,6,opt,name=stats,proto3" json:"stats,omitempty"`
|
||||
// For type == DEAD, an error is included.
|
||||
// TODO: solana-go doesn't currently expose this
|
||||
Err string `protobuf:"bytes,7,opt,name=err,proto3" json:"err,omitempty"`
|
||||
// Slot's leader as base58 string (looked up by the ingester)
|
||||
Leader string `protobuf:"bytes,8,opt,name=leader,proto3" json:"leader,omitempty"`
|
||||
// Source node identifier
|
||||
Source string `protobuf:"bytes,9,opt,name=source,proto3" json:"source,omitempty"`
|
||||
}
|
||||
|
||||
func (x *SlotStatus) Reset() {
|
||||
*x = SlotStatus{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_network_v1_slot_status_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *SlotStatus) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*SlotStatus) ProtoMessage() {}
|
||||
|
||||
func (x *SlotStatus) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_network_v1_slot_status_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use SlotStatus.ProtoReflect.Descriptor instead.
|
||||
func (*SlotStatus) Descriptor() ([]byte, []int) {
|
||||
return file_proto_network_v1_slot_status_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *SlotStatus) GetSlot() uint64 {
|
||||
if x != nil {
|
||||
return x.Slot
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *SlotStatus) GetTimestamp() uint64 {
|
||||
if x != nil {
|
||||
return x.Timestamp
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *SlotStatus) GetDelay() uint64 {
|
||||
if x != nil {
|
||||
return x.Delay
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *SlotStatus) GetType() SlotStatus_UpdateType {
|
||||
if x != nil {
|
||||
return x.Type
|
||||
}
|
||||
return SlotStatus_UPDATE_TYPE_UNSPECIFIED
|
||||
}
|
||||
|
||||
func (x *SlotStatus) GetParent() uint64 {
|
||||
if x != nil {
|
||||
return x.Parent
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *SlotStatus) GetStats() *TxStats {
|
||||
if x != nil {
|
||||
return x.Stats
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *SlotStatus) GetErr() string {
|
||||
if x != nil {
|
||||
return x.Err
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *SlotStatus) GetLeader() string {
|
||||
if x != nil {
|
||||
return x.Leader
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *SlotStatus) GetSource() string {
|
||||
if x != nil {
|
||||
return x.Source
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type TxStats struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
NumTransactionEntries uint64 `protobuf:"varint,1,opt,name=num_transaction_entries,json=numTransactionEntries,proto3" json:"num_transaction_entries,omitempty"`
|
||||
NumSuccessfulTransactions uint64 `protobuf:"varint,2,opt,name=num_successful_transactions,json=numSuccessfulTransactions,proto3" json:"num_successful_transactions,omitempty"`
|
||||
NumFailedTransactions uint64 `protobuf:"varint,3,opt,name=num_failed_transactions,json=numFailedTransactions,proto3" json:"num_failed_transactions,omitempty"`
|
||||
MaxTransactionsPerEntry uint64 `protobuf:"varint,4,opt,name=max_transactions_per_entry,json=maxTransactionsPerEntry,proto3" json:"max_transactions_per_entry,omitempty"`
|
||||
}
|
||||
|
||||
func (x *TxStats) Reset() {
|
||||
*x = TxStats{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_network_v1_slot_status_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *TxStats) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*TxStats) ProtoMessage() {}
|
||||
|
||||
func (x *TxStats) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_network_v1_slot_status_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use TxStats.ProtoReflect.Descriptor instead.
|
||||
func (*TxStats) Descriptor() ([]byte, []int) {
|
||||
return file_proto_network_v1_slot_status_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *TxStats) GetNumTransactionEntries() uint64 {
|
||||
if x != nil {
|
||||
return x.NumTransactionEntries
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *TxStats) GetNumSuccessfulTransactions() uint64 {
|
||||
if x != nil {
|
||||
return x.NumSuccessfulTransactions
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *TxStats) GetNumFailedTransactions() uint64 {
|
||||
if x != nil {
|
||||
return x.NumFailedTransactions
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *TxStats) GetMaxTransactionsPerEntry() uint64 {
|
||||
if x != nil {
|
||||
return x.MaxTransactionsPerEntry
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var File_proto_network_v1_slot_status_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_proto_network_v1_slot_status_proto_rawDesc = []byte{
|
||||
0x0a, 0x22, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f,
|
||||
0x76, 0x31, 0x2f, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6e, 0x65, 0x74, 0x77,
|
||||
0x6f, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x22, 0x94, 0x04, 0x0a, 0x0a, 0x53, 0x6c, 0x6f, 0x74, 0x53,
|
||||
0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d,
|
||||
0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x3b, 0x0a,
|
||||
0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53,
|
||||
0x6c, 0x6f, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
|
||||
0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x61,
|
||||
0x72, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65,
|
||||
0x6e, 0x74, 0x12, 0x2f, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72,
|
||||
0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74,
|
||||
0x61, 0x74, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x03, 0x65, 0x72, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18,
|
||||
0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x16, 0x0a,
|
||||
0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73,
|
||||
0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0xf5, 0x01, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
|
||||
0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x54,
|
||||
0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10,
|
||||
0x00, 0x12, 0x24, 0x0a, 0x20, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45,
|
||||
0x5f, 0x46, 0x49, 0x52, 0x53, 0x54, 0x5f, 0x53, 0x48, 0x52, 0x45, 0x44, 0x5f, 0x52, 0x45, 0x43,
|
||||
0x45, 0x49, 0x56, 0x45, 0x44, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x55, 0x50, 0x44, 0x41, 0x54,
|
||||
0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44,
|
||||
0x10, 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x59, 0x50,
|
||||
0x45, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x42, 0x41, 0x4e, 0x4b, 0x10, 0x03,
|
||||
0x12, 0x16, 0x0a, 0x12, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f,
|
||||
0x46, 0x52, 0x4f, 0x5a, 0x45, 0x4e, 0x10, 0x04, 0x12, 0x14, 0x0a, 0x10, 0x55, 0x50, 0x44, 0x41,
|
||||
0x54, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x45, 0x41, 0x44, 0x10, 0x05, 0x12, 0x27,
|
||||
0x0a, 0x23, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, 0x50,
|
||||
0x54, 0x49, 0x4d, 0x49, 0x53, 0x54, 0x49, 0x43, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d,
|
||||
0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x06, 0x12, 0x14, 0x0a, 0x10, 0x55, 0x50, 0x44, 0x41, 0x54,
|
||||
0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x07, 0x22, 0xf6, 0x01,
|
||||
0x0a, 0x07, 0x54, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x36, 0x0a, 0x17, 0x6e, 0x75, 0x6d,
|
||||
0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x74,
|
||||
0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x15, 0x6e, 0x75, 0x6d, 0x54,
|
||||
0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65,
|
||||
0x73, 0x12, 0x3e, 0x0a, 0x1b, 0x6e, 0x75, 0x6d, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73,
|
||||
0x66, 0x75, 0x6c, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x19, 0x6e, 0x75, 0x6d, 0x53, 0x75, 0x63, 0x63, 0x65,
|
||||
0x73, 0x73, 0x66, 0x75, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x73, 0x12, 0x36, 0x0a, 0x17, 0x6e, 0x75, 0x6d, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x5f,
|
||||
0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x04, 0x52, 0x15, 0x6e, 0x75, 0x6d, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x54, 0x72, 0x61,
|
||||
0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3b, 0x0a, 0x1a, 0x6d, 0x61, 0x78,
|
||||
0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x70, 0x65,
|
||||
0x72, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x17, 0x6d,
|
||||
0x61, 0x78, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x65,
|
||||
0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x6f, 0x2e, 0x66, 0x69, 0x72,
|
||||
0x65, 0x64, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x69, 0x6f, 0x2f, 0x72, 0x61, 0x64, 0x69, 0x61,
|
||||
0x6e, 0x63, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72,
|
||||
0x6b, 0x3b, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_proto_network_v1_slot_status_proto_rawDescOnce sync.Once
|
||||
file_proto_network_v1_slot_status_proto_rawDescData = file_proto_network_v1_slot_status_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_proto_network_v1_slot_status_proto_rawDescGZIP() []byte {
|
||||
file_proto_network_v1_slot_status_proto_rawDescOnce.Do(func() {
|
||||
file_proto_network_v1_slot_status_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_network_v1_slot_status_proto_rawDescData)
|
||||
})
|
||||
return file_proto_network_v1_slot_status_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_proto_network_v1_slot_status_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_proto_network_v1_slot_status_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_proto_network_v1_slot_status_proto_goTypes = []interface{}{
|
||||
(SlotStatus_UpdateType)(0), // 0: proto.network.v1.SlotStatus.UpdateType
|
||||
(*SlotStatus)(nil), // 1: proto.network.v1.SlotStatus
|
||||
(*TxStats)(nil), // 2: proto.network.v1.TxStats
|
||||
}
|
||||
var file_proto_network_v1_slot_status_proto_depIdxs = []int32{
|
||||
0, // 0: proto.network.v1.SlotStatus.type:type_name -> proto.network.v1.SlotStatus.UpdateType
|
||||
2, // 1: proto.network.v1.SlotStatus.stats:type_name -> proto.network.v1.TxStats
|
||||
2, // [2:2] is the sub-list for method output_type
|
||||
2, // [2:2] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
2, // [2:2] is the sub-list for extension extendee
|
||||
0, // [0:2] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_proto_network_v1_slot_status_proto_init() }
|
||||
func file_proto_network_v1_slot_status_proto_init() {
|
||||
if File_proto_network_v1_slot_status_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_proto_network_v1_slot_status_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*SlotStatus); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_network_v1_slot_status_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*TxStats); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_proto_network_v1_slot_status_proto_rawDesc,
|
||||
NumEnums: 1,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_proto_network_v1_slot_status_proto_goTypes,
|
||||
DependencyIndexes: file_proto_network_v1_slot_status_proto_depIdxs,
|
||||
EnumInfos: file_proto_network_v1_slot_status_proto_enumTypes,
|
||||
MessageInfos: file_proto_network_v1_slot_status_proto_msgTypes,
|
||||
}.Build()
|
||||
File_proto_network_v1_slot_status_proto = out.File
|
||||
file_proto_network_v1_slot_status_proto_rawDesc = nil
|
||||
file_proto_network_v1_slot_status_proto_goTypes = nil
|
||||
file_proto_network_v1_slot_status_proto_depIdxs = nil
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package proto.network.v1;
|
||||
|
||||
option go_package = "go.firedancer.io/radiance/proto/network;networkv1";
|
||||
|
||||
// See client/src/rpc_response.rs.
|
||||
message SlotStatus {
|
||||
// Slot number
|
||||
uint64 slot = 1;
|
||||
|
||||
// Millisecond UNIX timestamp of the observation on the Solana node.
|
||||
// Depends on accurate local clocks.
|
||||
uint64 timestamp = 2;
|
||||
|
||||
// One-way delay between the Solana node and the client.
|
||||
uint64 delay = 3;
|
||||
|
||||
// Update type
|
||||
enum UpdateType {
|
||||
UPDATE_TYPE_UNSPECIFIED = 0;
|
||||
UPDATE_TYPE_FIRST_SHRED_RECEIVED = 1;
|
||||
UPDATE_TYPE_COMPLETED = 2;
|
||||
UPDATE_TYPE_CREATED_BANK = 3;
|
||||
UPDATE_TYPE_FROZEN = 4;
|
||||
UPDATE_TYPE_DEAD = 5;
|
||||
UPDATE_TYPE_OPTIMISTIC_CONFIRMATION = 6;
|
||||
UPDATE_TYPE_ROOT = 7;
|
||||
}
|
||||
|
||||
UpdateType type = 4;
|
||||
|
||||
// For type == CREATED_BANK, the parent slot number is included.
|
||||
uint64 parent = 5;
|
||||
|
||||
// For type == FROZEN, extra transaction stats are included.
|
||||
TxStats stats = 6;
|
||||
|
||||
// For type == DEAD, an error is included.
|
||||
// TODO: solana-go doesn't currently expose this
|
||||
string err = 7;
|
||||
|
||||
// Slot's leader as base58 string (looked up by the ingester)
|
||||
string leader = 8;
|
||||
|
||||
// Source node identifier
|
||||
string source = 9;
|
||||
}
|
||||
|
||||
message TxStats {
|
||||
uint64 num_transaction_entries = 1;
|
||||
uint64 num_successful_transactions = 2;
|
||||
uint64 num_failed_transactions = 3;
|
||||
uint64 max_transactions_per_entry = 4;
|
||||
}
|
Loading…
Reference in New Issue