From b42b2a824e0b614c2b970d17ac3e6e14fe653164 Mon Sep 17 00:00:00 2001 From: Faulty Tolly <@faulttolerance.net> Date: Wed, 11 Sep 2024 11:45:43 +0200 Subject: [PATCH] include fraud checking --- fraud/types.go | 48 +++++++++++++++++++++ fraud/types_test.go | 103 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 fraud/types.go create mode 100644 fraud/types_test.go diff --git a/fraud/types.go b/fraud/types.go new file mode 100644 index 000000000..d2f3d7455 --- /dev/null +++ b/fraud/types.go @@ -0,0 +1,48 @@ +package fraud + +import ( + "context" + "errors" + "fmt" + + "github.com/dymensionxyz/dymint/types" +) + +type Fault struct { + Underlying error + + // Block defines the block in which the fault happened. + Block *types.Block +} + +func (f Fault) Error() string { + return fmt.Sprintf("fraud error: %s", f.Underlying) +} + +func (f Fault) Is(err error) bool { + fault, ok := (err).(Fault) + if !ok { + return false + } + return errors.Is(fault.Underlying, f.Underlying) +} + +func (f Fault) Unwrap() error { + return f.Underlying +} + +func (f Fault) GovProposalContent() string { + return f.Error() +} + +func NewFault(err error, block *types.Block) Fault { + return Fault{Underlying: err, Block: block} +} + +func IsFault(err error) bool { + return errors.As(err, &Fault{}) +} + +type Handler interface { + HandleFault(ctx context.Context, fault Fault) +} diff --git a/fraud/types_test.go b/fraud/types_test.go new file mode 100644 index 000000000..5e937aa1b --- /dev/null +++ b/fraud/types_test.go @@ -0,0 +1,103 @@ +package fraud_test + +import ( + "context" + "errors" + "testing" + + "github.com/dymensionxyz/dymint/fraud" + "github.com/dymensionxyz/dymint/types" +) + +func TestFault_Error(t *testing.T) { + underlyingErr := errors.New("test error") + fault := fraud.NewFault(underlyingErr, nil) + + expected := "fraud error: test error" + if fault.Error() != expected { + t.Errorf("Expected error message '%s', got '%s'", expected, fault.Error()) + } +} + +func TestFault_Is(t *testing.T) { + underlyingErr := errors.New("test error") + fault1 := fraud.NewFault(underlyingErr, nil) + fault2 := fraud.NewFault(underlyingErr, nil) + otherErr := errors.New("other error") + + if !fault1.Is(fault2) { + t.Error("Expected fault1.Is(fault2) to be true") + } + + if fault1.Is(otherErr) { + t.Error("Expected fault1.Is(otherErr) to be false") + } +} + +func TestFault_Unwrap(t *testing.T) { + underlyingErr := errors.New("test error") + fault := fraud.NewFault(underlyingErr, nil) + + if fault.Unwrap() != underlyingErr { + t.Error("Expected Unwrap() to return the underlying error") + } +} + +func TestFault_GovProposalContent(t *testing.T) { + underlyingErr := errors.New("test error") + fault := fraud.NewFault(underlyingErr, nil) + + expected := "fraud error: test error" + if fault.GovProposalContent() != expected { + t.Errorf("Expected GovProposalContent '%s', got '%s'", expected, fault.GovProposalContent()) + } +} + +func TestNewFault(t *testing.T) { + underlyingErr := errors.New("test error") + block := &types.Block{} + fault := fraud.NewFault(underlyingErr, block) + + if fault.Underlying != underlyingErr { + t.Error("Expected Underlying error to match") + } + + if fault.Block != block { + t.Error("Expected Block to match") + } +} + +func TestIsFault(t *testing.T) { + underlyingErr := errors.New("test error") + fault := fraud.NewFault(underlyingErr, nil) + + isFault := fraud.IsFault(fault) + if !isFault { + t.Error("Expected IsFault to return true for a Fault") + } + + isFault = fraud.IsFault(errors.New("not a fault")) + if isFault { + t.Error("Expected IsFault to return false for a non-Fault error") + } +} + +type mockHandler struct { + called bool +} + +func (m *mockHandler) HandleFault(ctx context.Context, fault fraud.Fault) { + m.called = true +} + +func TestHandler(t *testing.T) { + handler := &mockHandler{} + ctx := context.Background() + fault := fraud.NewFault(errors.New("test error"), nil) + + handler.HandleFault(ctx, fault) + + if !handler.called { + t.Error("Expected HandleFault to be called") + } +}