mirror of
https://github.com/luxfi/node.git
synced 2026-07-27 03:39:39 +00:00
Layer A — wire framing: github.com/luxfi/api/zap (unchanged) Layer B — service spec: github.com/luxfi/proto/rpcdb (transport-agnostic data carriers, was node/proto/zap/rpcdb) Layer C — service impl + transports: node/db/rpcdb/ - service.go transport-neutral Service wrapping database.Database - zap_server.go ZAP transport adapter (default; used by cevm) - grpc_server.go gRPC transport adapter (-tags=grpc) One Service. Many transport adapters. Adding a transport is a new adapter file wrapping *Service; storage logic stays in service.go. Removed (-1390 LOC of duplicate/dead code): - node/proto/zap/rpcdb/rpcdb.go (moved to luxfi/proto/rpcdb) - node/proto/rpcdb/rpcdb_zap.go (dead HandlerRegistry path, no callers) - node/proto/rpcdb/rpcdb_grpc.go (duplicated gRPC server, replaced by node/db/rpcdb/grpc_server.go) - node/db/rpcdb/db.go (re-export shim, replaced by Service) Consumers updated to import the canonical adapter at node/db/rpcdb: - vms/rpcchainvm/zap/client.go - vms/rpcchainvm/zap/client_dbserver_test.go - vms/rpcchainvm/zap/cevm_e2e_test.go go.mod: add `replace github.com/luxfi/proto => ../proto` for in-tree development of the central wire-types module. Tests: db/rpcdb (3/3) + rpcchainvm/zap (4/4 incl. cevm cross-process e2e — KP_META written via ZAP db channel, no fallback to local zapdb).
160 lines
5.4 KiB
Go
160 lines
5.4 KiB
Go
//go:build grpc
|
|
|
|
// Copyright (C) 2019-2026, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package rpcdb
|
|
|
|
import (
|
|
"context"
|
|
|
|
"google.golang.org/protobuf/types/known/emptypb"
|
|
|
|
"github.com/luxfi/database"
|
|
rpcdbpb "github.com/luxfi/node/proto/pb/rpcdb"
|
|
rpcdb "github.com/luxfi/proto/rpcdb"
|
|
)
|
|
|
|
// GRPCServer is the gRPC transport adapter for the rpcdb Service. It
|
|
// wraps *Service and translates gRPC's protobuf-generated request /
|
|
// response types into the transport-neutral wire types in
|
|
// github.com/luxfi/proto/rpcdb. Pure adapter — no storage logic
|
|
// lives here.
|
|
type GRPCServer struct {
|
|
rpcdbpb.UnimplementedDatabaseServer
|
|
svc *Service
|
|
}
|
|
|
|
// NewGRPCServer wraps a database.Database for serving over gRPC.
|
|
func NewGRPCServer(db database.Database) *GRPCServer {
|
|
return NewGRPCServerFromService(NewService(db))
|
|
}
|
|
|
|
// NewGRPCServerFromService wraps an existing Service for serving over
|
|
// gRPC. Symmetric with NewZAPServerFromService.
|
|
func NewGRPCServerFromService(svc *Service) *GRPCServer {
|
|
return &GRPCServer{svc: svc}
|
|
}
|
|
|
|
// Compile-time interface check.
|
|
var _ rpcdbpb.DatabaseServer = (*GRPCServer)(nil)
|
|
|
|
func toPbErr(code rpcdb.Error) rpcdbpb.Error {
|
|
switch code {
|
|
case rpcdb.Error_ERROR_NOT_FOUND:
|
|
return rpcdbpb.Error_ERROR_NOT_FOUND
|
|
case rpcdb.Error_ERROR_CLOSED:
|
|
return rpcdbpb.Error_ERROR_CLOSED
|
|
default:
|
|
return rpcdbpb.Error_ERROR_UNSPECIFIED
|
|
}
|
|
}
|
|
|
|
func (g *GRPCServer) Has(ctx context.Context, req *rpcdbpb.HasRequest) (*rpcdbpb.HasResponse, error) {
|
|
resp, err := g.svc.Has(ctx, &rpcdb.HasRequest{Key: req.Key})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &rpcdbpb.HasResponse{Has: resp.Has, Err: toPbErr(resp.Err)}, nil
|
|
}
|
|
|
|
func (g *GRPCServer) Get(ctx context.Context, req *rpcdbpb.GetRequest) (*rpcdbpb.GetResponse, error) {
|
|
resp, err := g.svc.Get(ctx, &rpcdb.GetRequest{Key: req.Key})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &rpcdbpb.GetResponse{Value: resp.Value, Err: toPbErr(resp.Err)}, nil
|
|
}
|
|
|
|
func (g *GRPCServer) Put(ctx context.Context, req *rpcdbpb.PutRequest) (*rpcdbpb.PutResponse, error) {
|
|
resp, err := g.svc.Put(ctx, &rpcdb.PutRequest{Key: req.Key, Value: req.Value})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &rpcdbpb.PutResponse{Err: toPbErr(resp.Err)}, nil
|
|
}
|
|
|
|
func (g *GRPCServer) Delete(ctx context.Context, req *rpcdbpb.DeleteRequest) (*rpcdbpb.DeleteResponse, error) {
|
|
resp, err := g.svc.Delete(ctx, &rpcdb.DeleteRequest{Key: req.Key})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &rpcdbpb.DeleteResponse{Err: toPbErr(resp.Err)}, nil
|
|
}
|
|
|
|
func (g *GRPCServer) WriteBatch(ctx context.Context, req *rpcdbpb.WriteBatchRequest) (*rpcdbpb.WriteBatchResponse, error) {
|
|
puts := make([]*rpcdb.PutRequest, len(req.Puts))
|
|
for i, p := range req.Puts {
|
|
puts[i] = &rpcdb.PutRequest{Key: p.Key, Value: p.Value}
|
|
}
|
|
dels := make([]*rpcdb.DeleteRequest, len(req.Deletes))
|
|
for i, d := range req.Deletes {
|
|
dels[i] = &rpcdb.DeleteRequest{Key: d.Key}
|
|
}
|
|
resp, err := g.svc.WriteBatch(ctx, &rpcdb.WriteBatchRequest{Puts: puts, Deletes: dels})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &rpcdbpb.WriteBatchResponse{Err: toPbErr(resp.Err)}, nil
|
|
}
|
|
|
|
func (g *GRPCServer) Compact(ctx context.Context, req *rpcdbpb.CompactRequest) (*rpcdbpb.CompactResponse, error) {
|
|
resp, err := g.svc.Compact(ctx, &rpcdb.CompactRequest{Start: req.Start, Limit: req.Limit})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &rpcdbpb.CompactResponse{Err: toPbErr(resp.Err)}, nil
|
|
}
|
|
|
|
func (g *GRPCServer) Close(ctx context.Context, _ *rpcdbpb.CloseRequest) (*rpcdbpb.CloseResponse, error) {
|
|
resp, err := g.svc.Close(ctx, &rpcdb.CloseRequest{})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &rpcdbpb.CloseResponse{Err: toPbErr(resp.Err)}, nil
|
|
}
|
|
|
|
func (g *GRPCServer) HealthCheck(ctx context.Context, _ *emptypb.Empty) (*rpcdbpb.HealthCheckResponse, error) {
|
|
resp, err := g.svc.HealthCheck(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &rpcdbpb.HealthCheckResponse{Details: resp.Details}, nil
|
|
}
|
|
|
|
func (g *GRPCServer) NewIteratorWithStartAndPrefix(ctx context.Context, req *rpcdbpb.NewIteratorWithStartAndPrefixRequest) (*rpcdbpb.NewIteratorWithStartAndPrefixResponse, error) {
|
|
resp, err := g.svc.NewIteratorWithStartAndPrefix(ctx, &rpcdb.NewIteratorWithStartAndPrefixRequest{Start: req.Start, Prefix: req.Prefix})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &rpcdbpb.NewIteratorWithStartAndPrefixResponse{Id: resp.Id}, nil
|
|
}
|
|
|
|
func (g *GRPCServer) IteratorNext(ctx context.Context, req *rpcdbpb.IteratorNextRequest) (*rpcdbpb.IteratorNextResponse, error) {
|
|
resp, err := g.svc.IteratorNext(ctx, &rpcdb.IteratorNextRequest{Id: req.Id})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
data := make([]*rpcdbpb.PutRequest, len(resp.Data))
|
|
for i, e := range resp.Data {
|
|
data[i] = &rpcdbpb.PutRequest{Key: e.Key, Value: e.Value}
|
|
}
|
|
return &rpcdbpb.IteratorNextResponse{Data: data}, nil
|
|
}
|
|
|
|
func (g *GRPCServer) IteratorError(ctx context.Context, req *rpcdbpb.IteratorErrorRequest) (*rpcdbpb.IteratorErrorResponse, error) {
|
|
resp, err := g.svc.IteratorError(ctx, &rpcdb.IteratorErrorRequest{Id: req.Id})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &rpcdbpb.IteratorErrorResponse{Err: toPbErr(resp.Err)}, nil
|
|
}
|
|
|
|
func (g *GRPCServer) IteratorRelease(ctx context.Context, req *rpcdbpb.IteratorReleaseRequest) (*rpcdbpb.IteratorReleaseResponse, error) {
|
|
resp, err := g.svc.IteratorRelease(ctx, &rpcdb.IteratorReleaseRequest{Id: req.Id})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &rpcdbpb.IteratorReleaseResponse{Err: toPbErr(resp.Err)}, nil
|
|
}
|