Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add middleware for checking that requested tick is within archiver's intervals #99

Merged
merged 3 commits into from
Feb 10, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions rpc/middleware.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package rpc

import (
"context"
"github.com/pkg/errors"
"github.com/qubic/go-archiver/protobuff"
"github.com/qubic/go-archiver/validator/tick"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

func (s *Server) tickNumberInterceptor(ctx context.Context, req any, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
LINCKODE marked this conversation as resolved.
Show resolved Hide resolved

var err error

switch request := req.(type) {

case *protobuff.GetTickRequestV2:
err = s.checkTickWithinArchiverIntervals(ctx, request.TickNumber)
case *protobuff.GetTickTransactionsRequest:
err = s.checkTickWithinArchiverIntervals(ctx, request.TickNumber)
case *protobuff.GetTickDataRequest:
err = s.checkTickWithinArchiverIntervals(ctx, request.TickNumber)
case *protobuff.GetQuorumTickDataRequest:
err = s.checkTickWithinArchiverIntervals(ctx, request.TickNumber)
case *protobuff.GetTickApprovedTransactionsRequest:
err = s.checkTickWithinArchiverIntervals(ctx, request.TickNumber)
case *protobuff.GetChainHashRequest:
err = s.checkTickWithinArchiverIntervals(ctx, request.TickNumber)
case *protobuff.GetTickTransactionsRequestV2:
err = s.checkTickWithinArchiverIntervals(ctx, request.TickNumber)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not important but can't you join the cases (like case 1, 2, 3, 4, 5, 6: ...) or use if. It seems that always the same function call is made. Why split it up into several cases?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree, it should be case *protobuff.GetTickApprovedTransactionsRequest, *protobuff.GetChainHashRequest, etc

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

joining the cases does not work, as they are different objects that do not inherit the TickNumber field, but have it defined individually. if i try to do it like @0xluk suggested, it gets treated as an any type, so i am back to square one

default:
break
}

if err != nil {
return nil, errors.Wrapf(err, "invalid tick number")
}

h, err := handler(ctx, req)

return h, err
}

func (s *Server) checkTickWithinArchiverIntervals(ctx context.Context, tickNumber uint32) error {

lastProcessedTick, err := s.store.GetLastProcessedTick(ctx)
if err != nil {
return status.Errorf(codes.Internal, "failed to get last processed tick")
}

if tickNumber > lastProcessedTick.TickNumber {
st := status.Newf(codes.FailedPrecondition, "requested tick number %d is greater than last processed tick %d", tickNumber, lastProcessedTick.TickNumber)
st, err = st.WithDetails(&protobuff.LastProcessedTick{LastProcessedTick: lastProcessedTick.TickNumber})
if err != nil {
return status.Errorf(codes.Internal, "creating custom status")
}
return st.Err()
}

processedTickIntervalsPerEpoch, err := s.store.GetProcessedTickIntervals(ctx)
if err != nil {
return status.Errorf(codes.Internal, "getting processed tick intervals per epoch")
}

wasSkipped, nextAvailableTick := tick.WasSkippedByArchive(tickNumber, processedTickIntervalsPerEpoch)
if wasSkipped == true {
st := status.Newf(codes.OutOfRange, "provided tick number %d was skipped by the system, next available tick is %d", tickNumber, nextAvailableTick)
st, err = st.WithDetails(&protobuff.NextAvailableTick{NextTickNumber: nextAvailableTick})
if err != nil {
return status.Errorf(codes.Internal, "creating custom status")
}
return st.Err()
}

return nil
}
118 changes: 1 addition & 117 deletions rpc/rpc_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,36 +82,6 @@ func getTransactionInfo(ctx context.Context, pebbleStore *store.PebbleStore, tra
}

func (s *Server) GetTickData(ctx context.Context, req *protobuff.GetTickDataRequest) (*protobuff.GetTickDataResponse, error) {
lastProcessedTick, err := s.store.GetLastProcessedTick(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "getting last processed tick: %v", err)
}
if req.TickNumber > lastProcessedTick.TickNumber {
st := status.Newf(codes.FailedPrecondition, "requested tick number %d is greater than last processed tick %d", req.TickNumber, lastProcessedTick.TickNumber)
st, err = st.WithDetails(&protobuff.LastProcessedTick{LastProcessedTick: lastProcessedTick.TickNumber})
if err != nil {
return nil, status.Errorf(codes.Internal, "creating custom status")
}

return nil, st.Err()
}

processedTickIntervalsPerEpoch, err := s.store.GetProcessedTickIntervals(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "getting processed tick intervals per epoch")
}

wasSkipped, nextAvailableTick := tick.WasSkippedByArchive(req.TickNumber, processedTickIntervalsPerEpoch)
if wasSkipped == true {
st := status.Newf(codes.OutOfRange, "provided tick number %d was skipped by the system, next available tick is %d", req.TickNumber, nextAvailableTick)
st, err = st.WithDetails(&protobuff.NextAvailableTick{NextTickNumber: nextAvailableTick})
if err != nil {
return nil, status.Errorf(codes.Internal, "creating custom status")
}

return nil, st.Err()
}

tickData, err := s.store.GetTickData(ctx, req.TickNumber)
if err != nil {
if errors.Is(err, store.ErrNotFound) {
Expand All @@ -131,35 +101,6 @@ func (s *Server) GetTickData(ctx context.Context, req *protobuff.GetTickDataRequ
return &protobuff.GetTickDataResponse{TickData: tickData}, nil
}
func (s *Server) GetTickTransactions(ctx context.Context, req *protobuff.GetTickTransactionsRequest) (*protobuff.GetTickTransactionsResponse, error) {
lastProcessedTick, err := s.store.GetLastProcessedTick(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "getting last processed tick: %v", err)
}
if req.TickNumber > lastProcessedTick.TickNumber {
st := status.Newf(codes.FailedPrecondition, "requested tick number %d is greater than last processed tick %d", req.TickNumber, lastProcessedTick.TickNumber)
st, err = st.WithDetails(&protobuff.LastProcessedTick{LastProcessedTick: lastProcessedTick.TickNumber})
if err != nil {
return nil, status.Errorf(codes.Internal, "creating custom status")
}

return nil, st.Err()
}

processedTickIntervalsPerEpoch, err := s.store.GetProcessedTickIntervals(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "getting processed tick intervals per epoch")
}

wasSkipped, nextAvailableTick := tick.WasSkippedByArchive(req.TickNumber, processedTickIntervalsPerEpoch)
if wasSkipped == true {
st := status.Newf(codes.OutOfRange, "provided tick number %d was skipped by the system, next available tick is %d", req.TickNumber, nextAvailableTick)
st, err = st.WithDetails(&protobuff.NextAvailableTick{NextTickNumber: nextAvailableTick})
if err != nil {
return nil, status.Errorf(codes.Internal, "creating custom status")
}

return nil, st.Err()
}

txs, err := s.store.GetTickTransactions(ctx, req.TickNumber)
if err != nil {
Expand All @@ -173,35 +114,6 @@ func (s *Server) GetTickTransactions(ctx context.Context, req *protobuff.GetTick
}

func (s *Server) GetTickTransferTransactions(ctx context.Context, req *protobuff.GetTickTransactionsRequest) (*protobuff.GetTickTransactionsResponse, error) {
lastProcessedTick, err := s.store.GetLastProcessedTick(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "getting last processed tick: %v", err)
}
if req.TickNumber > lastProcessedTick.TickNumber {
st := status.Newf(codes.FailedPrecondition, "requested tick number %d is greater than last processed tick %d", req.TickNumber, lastProcessedTick.TickNumber)
st, err = st.WithDetails(&protobuff.LastProcessedTick{LastProcessedTick: lastProcessedTick.TickNumber})
if err != nil {
return nil, status.Errorf(codes.Internal, "creating custom status")
}

return nil, st.Err()
}

processedTickIntervalsPerEpoch, err := s.store.GetProcessedTickIntervals(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "getting processed tick intervals per epoch")
}

wasSkipped, nextAvailableTick := tick.WasSkippedByArchive(req.TickNumber, processedTickIntervalsPerEpoch)
if wasSkipped == true {
st := status.Newf(codes.OutOfRange, "provided tick number %d was skipped by the system, next available tick is %d", req.TickNumber, nextAvailableTick)
st, err = st.WithDetails(&protobuff.NextAvailableTick{NextTickNumber: nextAvailableTick})
if err != nil {
return nil, status.Errorf(codes.Internal, "creating custom status")
}

return nil, st.Err()
}

txs, err := s.store.GetTickTransferTransactions(ctx, req.TickNumber)
if err != nil {
Expand Down Expand Up @@ -474,35 +386,6 @@ func (s *Server) GetTransferTransactionsPerTick(ctx context.Context, req *protob
}

func (s *Server) GetTickApprovedTransactions(ctx context.Context, req *protobuff.GetTickApprovedTransactionsRequest) (*protobuff.GetTickApprovedTransactionsResponse, error) {
lastProcessedTick, err := s.store.GetLastProcessedTick(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "getting last processed tick: %v", err)
}
if req.TickNumber > lastProcessedTick.TickNumber {
st := status.Newf(codes.FailedPrecondition, "requested tick number %d is greater than last processed tick %d", req.TickNumber, lastProcessedTick.TickNumber)
st, err = st.WithDetails(&protobuff.LastProcessedTick{LastProcessedTick: lastProcessedTick.TickNumber})
if err != nil {
return nil, status.Errorf(codes.Internal, "creating custom status")
}

return nil, st.Err()
}

processedTickIntervalsPerEpoch, err := s.store.GetProcessedTickIntervals(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "getting processed tick intervals per epoch")
}

wasSkipped, nextAvailableTick := tick.WasSkippedByArchive(req.TickNumber, processedTickIntervalsPerEpoch)
if wasSkipped == true {
st := status.Newf(codes.OutOfRange, "provided tick number %d was skipped by the system, next available tick is %d", req.TickNumber, nextAvailableTick)
st, err = st.WithDetails(&protobuff.NextAvailableTick{NextTickNumber: nextAvailableTick})
if err != nil {
return nil, status.Errorf(codes.Internal, "creating custom status")
}

return nil, st.Err()
}

tts, err := s.store.GetTickTransactionsStatus(ctx, uint64(req.TickNumber))
if err != nil {
Expand Down Expand Up @@ -641,6 +524,7 @@ func (s *Server) Start() error {
srv := grpc.NewServer(
grpc.MaxRecvMsgSize(600*1024*1024),
grpc.MaxSendMsgSize(600*1024*1024),
grpc.UnaryInterceptor(s.tickNumberInterceptor),
)
protobuff.RegisterArchiveServiceServer(srv, s)
reflection.Register(srv)
Expand Down
88 changes: 0 additions & 88 deletions rpc/v2_endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"context"
"encoding/hex"
"github.com/cockroachdb/pebble"
"github.com/qubic/go-archiver/validator/tick"
"slices"

"github.com/pkg/errors"
Expand Down Expand Up @@ -53,35 +52,6 @@ func (s *Server) GetTickTransactionsV2(ctx context.Context, req *protobuff.GetTi
}

func (s *Server) GetAllTickTransactionsV2(ctx context.Context, req *protobuff.GetTickRequestV2) (*protobuff.GetTickTransactionsResponseV2, error) {
lastProcessedTick, err := s.store.GetLastProcessedTick(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "getting last processed tick: %v", err)
}
if req.TickNumber > lastProcessedTick.TickNumber {
st := status.Newf(codes.FailedPrecondition, "requested tick number %d is greater than last processed tick %d", req.TickNumber, lastProcessedTick.TickNumber)
st, err = st.WithDetails(&protobuff.LastProcessedTick{LastProcessedTick: lastProcessedTick.TickNumber})
if err != nil {
return nil, status.Errorf(codes.Internal, "creating custom status")
}

return nil, st.Err()
}

processedTickIntervalsPerEpoch, err := s.store.GetProcessedTickIntervals(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "getting processed tick intervals per epoch")
}

wasSkipped, nextAvailableTick := tick.WasSkippedByArchive(req.TickNumber, processedTickIntervalsPerEpoch)
if wasSkipped == true {
st := status.Newf(codes.OutOfRange, "provided tick number %d was skipped by the system, next available tick is %d", req.TickNumber, nextAvailableTick)
st, err = st.WithDetails(&protobuff.NextAvailableTick{NextTickNumber: nextAvailableTick})
if err != nil {
return nil, status.Errorf(codes.Internal, "creating custom status")
}

return nil, st.Err()
}

txs, err := s.store.GetTickTransactions(ctx, req.TickNumber)
if err != nil {
Expand Down Expand Up @@ -112,35 +82,6 @@ func (s *Server) GetAllTickTransactionsV2(ctx context.Context, req *protobuff.Ge
}

func (s *Server) GetTransferTickTransactionsV2(ctx context.Context, req *protobuff.GetTickRequestV2) (*protobuff.GetTickTransactionsResponseV2, error) {
lastProcessedTick, err := s.store.GetLastProcessedTick(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "getting last processed tick: %v", err)
}
if req.TickNumber > lastProcessedTick.TickNumber {
st := status.Newf(codes.FailedPrecondition, "requested tick number %d is greater than last processed tick %d", req.TickNumber, lastProcessedTick.TickNumber)
st, err = st.WithDetails(&protobuff.LastProcessedTick{LastProcessedTick: lastProcessedTick.TickNumber})
if err != nil {
return nil, status.Errorf(codes.Internal, "creating custom status")
}

return nil, st.Err()
}

processedTickIntervalsPerEpoch, err := s.store.GetProcessedTickIntervals(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "getting processed tick intervals per epoch")
}

wasSkipped, nextAvailableTick := tick.WasSkippedByArchive(req.TickNumber, processedTickIntervalsPerEpoch)
if wasSkipped == true {
st := status.Newf(codes.OutOfRange, "provided tick number %d was skipped by the system, next available tick is %d", req.TickNumber, nextAvailableTick)
st, err = st.WithDetails(&protobuff.NextAvailableTick{NextTickNumber: nextAvailableTick})
if err != nil {
return nil, status.Errorf(codes.Internal, "creating custom status")
}

return nil, st.Err()
}

txs, err := s.store.GetTickTransferTransactions(ctx, req.TickNumber)
if err != nil {
Expand Down Expand Up @@ -171,35 +112,6 @@ func (s *Server) GetTransferTickTransactionsV2(ctx context.Context, req *protobu
}

func (s *Server) GetApprovedTickTransactionsV2(ctx context.Context, req *protobuff.GetTickRequestV2) (*protobuff.GetTickTransactionsResponseV2, error) {
lastProcessedTick, err := s.store.GetLastProcessedTick(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "getting last processed tick: %v", err)
}
if req.TickNumber > lastProcessedTick.TickNumber {
st := status.Newf(codes.FailedPrecondition, "requested tick number %d is greater than last processed tick %d", req.TickNumber, lastProcessedTick.TickNumber)
st, err = st.WithDetails(&protobuff.LastProcessedTick{LastProcessedTick: lastProcessedTick.TickNumber})
if err != nil {
return nil, status.Errorf(codes.Internal, "creating custom status")
}

return nil, st.Err()
}

processedTickIntervalsPerEpoch, err := s.store.GetProcessedTickIntervals(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "getting processed tick intervals per epoch")
}

wasSkipped, nextAvailableTick := tick.WasSkippedByArchive(req.TickNumber, processedTickIntervalsPerEpoch)
if wasSkipped == true {
st := status.Newf(codes.OutOfRange, "provided tick number %d was skipped by the system, next available tick is %d", req.TickNumber, nextAvailableTick)
st, err = st.WithDetails(&protobuff.NextAvailableTick{NextTickNumber: nextAvailableTick})
if err != nil {
return nil, status.Errorf(codes.Internal, "creating custom status")
}

return nil, st.Err()
}

txs, err := s.store.GetTickTransferTransactions(ctx, req.TickNumber)
if err != nil {
Expand Down
Loading