Skip to content

Conversation

@PastaPastaPasta
Copy link
Member

Issue being fixed or feature implemented

Removed non-generic maybe_error and replaced with a generic Result class paired with Ok and Err structs

What was done?

This is a simple implementation of the Result type in C++. The Result type is a type that can either be an Ok value, which represents a successful operation and contains a value, or an Err value, which represents a failed operation and contains an error value.

The Result class is a template class that takes two types: T, which is the type of the value that an Ok result will contain, and E, which is the type of the value that an Err result will contain.

The Ok and Err structs are also templates, and are used to construct Ok and Err values. The Ok struct has a single member val_ of type T, and the Err struct has a single member val_ of type E.

The Result class has a constructor that takes either an Ok value or an Err value, and stores the value internally. It also has several member functions that can be used to access the value of the Result and check whether it is an Ok or Err value.

The is_ok() and is_err() member functions can be used to check whether the Result is an Ok or Err value, respectively. The operator bool() function allows the Result to be used in a boolean context, such as an if statement. The unwrap() and unwrap_err() member functions can be used to get the value contained in the Result, but will assert if the Result is not of the expected type.

How Has This Been Tested?

building, unit tests

Breaking Changes

Should be none

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

@PastaPastaPasta PastaPastaPasta added this to the 19 milestone Dec 15, 2022
Copy link
Collaborator

@knst knst left a comment

Choose a reason for hiding this comment

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

My concern, that class Result always allocate memory for both type Ok and E.

    Ok<T> val_;
    E err_;

So far as I can see all Ok<> and E<> requires default construct that will be called whatever Result succeed case or not.
Also it always consume memory for both Ok and E even if it is only one needed.

That's fine if it is an implementation for small and rarely used component.
But if the Result is supposed to be general util component it will spread someday all over code base and will effect both performance and memory consumption and it is far from production ready.

I think wrapper over std::variant will work better.

@PastaPastaPasta
Copy link
Member Author

My concern, that class Result always allocate memory for both type Ok and E.


    Ok<T> val_;

    E err_;

So far as I can see all Ok<> and E<> requires default construct that will be called whatever Result succeed case or not.

Also it always consume memory for both Ok and E even if it is only one needed.

That's fine if it is an implementation for small and rarely used component.

But if the Result is supposed to be general util component it will spread someday all over code base and will effect both performance and memory consumption and it is far from production ready.

I think wrapper over std::variant will work better.

I am worried about this. I think that we could add some static asserts which ensure the types are trivially constructible.

@PastaPastaPasta
Copy link
Member Author

Variant seems to work fine, how does that look?

@PastaPastaPasta PastaPastaPasta requested a review from knst December 15, 2022 16:40
Copy link
Collaborator

@knst knst left a comment

Choose a reason for hiding this comment

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

Please, check this branch: develop...knst:dash:refac/result

@github-actions
Copy link

This pull request has conflicts, please rebase.

@github-actions
Copy link

github-actions bot commented Feb 3, 2023

This pull request has conflicts, please rebase.

PastaPastaPasta added a commit that referenced this pull request Feb 19, 2023
## Issue being fixed or feature implemented
This refactoring helps to make code more specific and clear.
There's using syntax feature from modern C++ such as 'enum class',
structure bindings in loops, declaration variables inside if/switch
statements, etc.


## What was done?
This PR is based on @PastaPastaPasta 's PR
#4472

There excluded changes related to using std::optional. Let's decide
firstly about `Result` class: #5109


## How Has This Been Tested?
Run unit/functional tests

## Breaking Changes
No breaking changes

## Checklist:
- [x] I have performed a self-review of my own code
- [x] I have assigned this pull request to a milestone

---------

Co-authored-by: Pasta <[email protected]>
@UdjinM6 UdjinM6 modified the milestones: 19, 20 Feb 27, 2023
knst
knst previously approved these changes Mar 6, 2023
Copy link
Collaborator

@knst knst left a comment

Choose a reason for hiding this comment

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

utACK

@PastaPastaPasta PastaPastaPasta requested a review from UdjinM6 March 20, 2023 15:27
knst added a commit to knst/dash that referenced this pull request Apr 10, 2023
…lementation

Since last refactoring bitcoin#15921 and bitcoin#17004 the benefits of using maybe_error are less significants
because the interface became simpler.

In future it can be considered using universal `maybe_error` (Result) as proposed in PR dashpay#5109 instead this particular implementation
knst added a commit to knst/dash that referenced this pull request Apr 10, 2023
…lementation

Since last refactoring bitcoin#15921 and bitcoin#17004 the benefits of using maybe_error are less significants
because the interface became simpler.

In future it can be considered using universal `maybe_error` (Result) as proposed in PR dashpay#5109 instead this particular implementation
knst added a commit to knst/dash that referenced this pull request Apr 10, 2023
…lementation

Since last refactoring bitcoin#15921 and bitcoin#17004 the benefits of using maybe_error are less significants
because the interface became simpler.

In future it can be considered using universal `maybe_error` (Result) as proposed in PR dashpay#5109 instead this particular implementation
UdjinM6
UdjinM6 previously approved these changes Apr 15, 2023
Copy link

@UdjinM6 UdjinM6 left a comment

Choose a reason for hiding this comment

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

utACK

knst added a commit to knst/dash that referenced this pull request Apr 15, 2023
…lementation

Since last refactoring bitcoin#15921 and bitcoin#17004 the benefits of using maybe_error are less significants
because the interface became simpler.

In future it can be considered using universal `maybe_error` (Result) as proposed in PR dashpay#5109 instead this particular implementation
knst
knst previously approved these changes Apr 15, 2023
Copy link
Collaborator

@knst knst left a comment

Choose a reason for hiding this comment

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

LGTM

@UdjinM6 UdjinM6 dismissed their stale review April 15, 2023 22:45

let's wait for cd2901e/5309

knst added a commit to knst/dash that referenced this pull request Apr 16, 2023
…lementation

Since last refactoring bitcoin#15921 and bitcoin#17004 the benefits of using maybe_error are less significants
because the interface became simpler.

In future it can be considered using universal `maybe_error` (Result) as proposed in PR dashpay#5109 instead this particular implementation
knst added a commit to knst/dash that referenced this pull request Apr 17, 2023
…lementation

Since last refactoring bitcoin#15921 and bitcoin#17004 the benefits of using maybe_error are less significants
because the interface became simpler.

In future it can be considered using universal `maybe_error` (Result) as proposed in PR dashpay#5109 instead this particular implementation
@github-actions
Copy link

This pull request has conflicts, please rebase.

knst added a commit to knst/dash that referenced this pull request Apr 17, 2023
…lementation

Since last refactoring bitcoin#15921 and bitcoin#17004 the benefits of using maybe_error are less significants
because the interface became simpler.

In future it can be considered using universal `maybe_error` (Result) as proposed in PR dashpay#5109 instead this particular implementation
UdjinM6 pushed a commit that referenced this pull request Apr 25, 2023
…h bitcoin implementation (#5335)

## Issue being fixed or feature implemented
The benefits of using custom struct `maybe_error` is less significant
since the interface `TxValidationState` became simpler after
refactorings from bitcoin#15921 and bitcoin#17004

The refactoring of `maybe_error` as a class result from PR #5109 is
still useful but not for case of TxValidationState.



## What was done?
Unified using TxValidationState in dash's related code.

## How Has This Been Tested?
Run unit/functional tests


## Breaking Changes
No breaking changes, logic are same.

## Checklist:
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have added or updated relevant unit/integration/functional/e2e
tests
- [ ] I have made corresponding changes to the documentation
- [x] I have assigned this pull request to a milestone
@github-actions
Copy link

This pull request has conflicts, please rebase.

@knst
Copy link
Collaborator

knst commented Jul 24, 2023

Let's get this one merged! @PastaPastaPasta
Please, check this commit - knst@2bd3d06

p.s. The usages from validation.cpp and evo/ has been replaced to BlockValidationState and TxValidationState to follow bitcoin's changes.

This is a simple implementation of the Result type in C++. The Result type is a type that can either be an Ok value, which represents a successful operation and contains a value, or an Err value, which represents a failed operation and contains an error value.

The Result class is a template class that takes two types: T, which is the type of the value that an Ok result will contain, and E, which is the type of the value that an Err result will contain.

The Ok and Err structs are also templates, and are used to construct Ok and Err values. The Ok struct has an optional single member val_ of type T, and the Err struct has a single member val_ of type E.

The Result class has a constructor that takes either an Ok value or an Err value, and stores the value internally. It also has several member functions that can be used to access the value of the Result and check whether it is an Ok or Err value.

The is_ok() and is_err() member functions can be used to check whether the Result is an Ok or Err value, respectively. The operator bool() function allows the Result to be used in a boolean context, such as an if statement. The unwrap() and err() member functions can be used to get the value contained in the Result, but will assert if the Result is not of the expected type.

For parametrizing maybe_error with Ok without value, should be used template Ok<void>, you can return just {} in this case as success.

Co-Authored-By: Konstantin Akimov <[email protected]>
@PastaPastaPasta
Copy link
Member Author

PastaPastaPasta commented Sep 29, 2023

Reviving this PR, currently with no usage; I would like to point towards an implementation of std::expected (which operated similar to Result) here: https://github.com/TartanLlama/expected

please provide conceptual review, especially on if we want to use a Result type class or tl::expected (https://en.cppreference.com/w/cpp/utility/expected)

@knst knst modified the milestones: 20, 21 Oct 23, 2023
@UdjinM6 UdjinM6 modified the milestones: 21, 20.1 Nov 14, 2023
@knst
Copy link
Collaborator

knst commented Jan 13, 2024

Reviving this PR, currently with no usage; I would like to point towards an implementation of std::expected

std::expected is indeed a better option.

Super-seeded by https://github.com/dashpay/dash/blob/develop/src/util/expected.h from #5782

@knst knst closed this Jan 13, 2024
@UdjinM6 UdjinM6 removed this from the 20.1 milestone Jan 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants