mirror of
https://github.com/luxfi/node.git
synced 2026-07-27 03:39:39 +00:00
159 lines
3.9 KiB
Go
159 lines
3.9 KiB
Go
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
//go:build skip
|
|
|
|
package sync
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/luxfi/metric"
|
|
"github.com/stretchr/testify/require"
|
|
"google.golang.org/protobuf/proto"
|
|
|
|
"github.com/luxfi/consensus/core"
|
|
"github.com/luxfi/ids"
|
|
"github.com/luxfi/node/trace"
|
|
"github.com/luxfi/node/x/merkledb"
|
|
"github.com/luxfi/p2p"
|
|
"github.com/luxfi/node/trace"
|
|
)
|
|
|
|
var _ p2p.Handler = (*flakyHandler)(nil)
|
|
|
|
func newDefaultDBConfig() merkledb.Config {
|
|
return merkledb.Config{
|
|
IntermediateWriteBatchSize: 100,
|
|
HistoryLength: defaultRequestKeyLimit,
|
|
ValueNodeCacheSize: defaultRequestKeyLimit,
|
|
IntermediateWriteBufferSize: defaultRequestKeyLimit,
|
|
IntermediateNodeCacheSize: defaultRequestKeyLimit,
|
|
Reg: metric.NewNoOp().Registry(),
|
|
Tracer: trace.Noop,
|
|
BranchFactor: merkledb.BranchFactor16,
|
|
}
|
|
}
|
|
|
|
func newFlakyRangeProofHandler(
|
|
t *testing.T,
|
|
db merkledb.MerkleDB,
|
|
modifyResponse func(response *merkledb.RangeProof),
|
|
) p2p.Handler {
|
|
handler := NewGetRangeProofHandler(db)
|
|
|
|
c := counter{m: 2}
|
|
return &p2p.TestHandler{
|
|
RequestF: func(ctx context.Context, nodeID ids.NodeID, deadline time.Time, requestBytes []byte) ([]byte, *common.Error) {
|
|
responseBytes, appErr := handler.Request(ctx, nodeID, deadline, requestBytes)
|
|
if appErr != nil {
|
|
return nil, appErr
|
|
}
|
|
|
|
response := &pb.RangeProof{}
|
|
require.NoError(t, proto.Unmarshal(responseBytes, response))
|
|
|
|
proof := &merkledb.RangeProof{}
|
|
require.NoError(t, proof.UnmarshalProto(response))
|
|
|
|
// Half of requests are modified
|
|
if c.Inc() == 0 {
|
|
modifyResponse(proof)
|
|
}
|
|
|
|
responseBytes, err := proto.Marshal(proof.ToProto())
|
|
if err != nil {
|
|
return nil, &common.Error{Code: 123, Message: err.Error()}
|
|
}
|
|
|
|
return responseBytes, nil
|
|
},
|
|
}
|
|
}
|
|
|
|
func newFlakyChangeProofHandler(
|
|
t *testing.T,
|
|
db merkledb.MerkleDB,
|
|
modifyResponse func(response *merkledb.ChangeProof),
|
|
) p2p.Handler {
|
|
handler := NewGetChangeProofHandler(db)
|
|
|
|
c := counter{m: 2}
|
|
return &p2p.TestHandler{
|
|
RequestF: func(ctx context.Context, nodeID ids.NodeID, deadline time.Time, requestBytes []byte) ([]byte, *common.Error) {
|
|
var err error
|
|
responseBytes, appErr := handler.Request(ctx, nodeID, deadline, requestBytes)
|
|
if appErr != nil {
|
|
return nil, appErr
|
|
}
|
|
|
|
response := &pb.SyncGetChangeProofResponse{}
|
|
require.NoError(t, proto.Unmarshal(responseBytes, response))
|
|
|
|
changeProof := response.Response.(*pb.SyncGetChangeProofResponse_ChangeProof)
|
|
proof := &merkledb.ChangeProof{}
|
|
require.NoError(t, proof.UnmarshalProto(changeProof.ChangeProof))
|
|
|
|
// Half of requests are modified
|
|
if c.Inc() == 0 {
|
|
modifyResponse(proof)
|
|
}
|
|
|
|
responseBytes, err = proto.Marshal(&pb.SyncGetChangeProofResponse{
|
|
Response: &pb.SyncGetChangeProofResponse_ChangeProof{
|
|
ChangeProof: proof.ToProto(),
|
|
},
|
|
})
|
|
if err != nil {
|
|
return nil, &common.Error{Code: 123, Message: err.Error()}
|
|
}
|
|
|
|
return responseBytes, nil
|
|
},
|
|
}
|
|
}
|
|
|
|
type flakyHandler struct {
|
|
p2p.Handler
|
|
c *counter
|
|
}
|
|
|
|
func (f *flakyHandler) Request(ctx context.Context, nodeID ids.NodeID, deadline time.Time, requestBytes []byte) ([]byte, *common.Error) {
|
|
if f.c.Inc() == 0 {
|
|
return nil, &common.Error{Code: 123, Message: "flake error"}
|
|
}
|
|
|
|
return f.Handler.Request(ctx, nodeID, deadline, requestBytes)
|
|
}
|
|
|
|
type counter struct {
|
|
i int
|
|
m int
|
|
lock sync.Mutex
|
|
}
|
|
|
|
func (c *counter) Inc() int {
|
|
c.lock.Lock()
|
|
defer c.lock.Unlock()
|
|
|
|
tmp := c.i
|
|
result := tmp % c.m
|
|
|
|
c.i++
|
|
return result
|
|
}
|
|
|
|
type waitingHandler struct {
|
|
p2p.NoOpHandler
|
|
handler p2p.Handler
|
|
updatedRootChan chan struct{}
|
|
}
|
|
|
|
func (w *waitingHandler) Request(ctx context.Context, nodeID ids.NodeID, deadline time.Time, requestBytes []byte) ([]byte, *common.Error) {
|
|
<-w.updatedRootChan
|
|
return w.handler.Request(ctx, nodeID, deadline, requestBytes)
|
|
}
|