-
Notifications
You must be signed in to change notification settings - Fork 462
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
Refactor TxValidator
#7386
Refactor TxValidator
#7386
Conversation
- Reduce burden on implementators
- Construct per TxType validator
- Avoid code duplication through inheritance
- By default this validator does not check anything (existing behavior)
|
||
namespace Nethermind.Blockchain.Test.Validators | ||
{ | ||
public class TestTxValidator : ITxValidator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused class
@@ -8,21 +8,11 @@ | |||
|
|||
namespace Nethermind.Optimism; | |||
|
|||
public class OptimismTxValidator : ITxValidator | |||
public sealed class OptimismTxValidator : ITxValidator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The existing OptimismTxValidator
always validates transactions that are of TxType.Deposit
without performing any checks. This does not look correct since there are validations that are performed on all existing TxType
s like IntrinsicGasTxValidator
but I might be missing some context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe @jmederosalvarado knows more about this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deposit transactions are special types, I think there should only be one per block on first step. Ping @jmederosalvarado , @deffrian or @flcl42 about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DepositTxs are mostly validated on L1 smart contract, and later by the CL client. Whatever DepositTx the CL feeds to the EL client is already valid.
- Avoid allocations
- Avoid allocations
- Avoid allocations
- Avoid allocations
- Avoid allocations
- No need to separate things
@@ -8,21 +8,11 @@ | |||
|
|||
namespace Nethermind.Optimism; | |||
|
|||
public class OptimismTxValidator : ITxValidator | |||
public sealed class OptimismTxValidator : ITxValidator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe @jmederosalvarado knows more about this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall I like it, just some details
@@ -8,21 +8,11 @@ | |||
|
|||
namespace Nethermind.Optimism; | |||
|
|||
public class OptimismTxValidator : ITxValidator | |||
public sealed class OptimismTxValidator : ITxValidator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deposit transactions are special types, I think there should only be one per block on first step. Ping @jmederosalvarado , @deffrian or @flcl42 about it.
@@ -208,7 +208,7 @@ public ISealEngine SealEngine | |||
public ITxPoolInfoProvider? TxPoolInfoProvider { get; set; } | |||
public IHealthHintService? HealthHintService { get; set; } | |||
public IRpcCapabilitiesProvider? RpcCapabilitiesProvider { get; set; } | |||
public ITxValidator? TxValidator { get; set; } | |||
public TxValidator? TxValidator { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like this to remain an interface. Any reason not to?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to change it to a concrete class since during initialization we might want to register validators for new TxType
s:
_api.TxValidator.WithValidator(TxType.DepositTx, new OptimismTxValidator()), |
@@ -74,7 +74,7 @@ public interface IApiWithBlockchain : IApiWithStores, IBlockchainBridgeFactory | |||
IHealthHintService? HealthHintService { get; set; } | |||
IRpcCapabilitiesProvider? RpcCapabilitiesProvider { get; set; } | |||
ITransactionComparerProvider? TransactionComparerProvider { get; set; } | |||
ITxValidator? TxValidator { get; set; } | |||
TxValidator? TxValidator { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like this to remain an interface. Any reason not to?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Required due to the change on NethermindApi
|
||
public TxValidator(ulong chainId) | ||
public TxValidator WithValidator(TxType type, ITxValidator validator) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having something like WithValidator
mutate the object itself looks weird. I'm not sure if this is how we do it in other parts of the code. I know we do it for object builders (e.g. TransactionBuilder
) but not for the object itself
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would implement WithValidator
as a clone, that is, return a new TxValidator
with the added validator, but I thought that it made little sense to pay for that due to our use case. Do you have any specific suggestion?
Co-authored-by: Jorge Mederos <46798594+jmederosalvarado@users.noreply.github.com>
# Conflicts: # src/Nethermind/Nethermind.Optimism/InitializeBlockchainOptimism.cs
public bool IsEip1559Enabled | ||
{ | ||
get => _isEip1559Enabled || IsEip4844Enabled; | ||
set => _isEip1559Enabled = value; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NOTE: we might want to revisit this later since EIPs can require other EIPs, and those can have their own requirements and so forth.
This approach is kind of fragile, for example, EIP 4844 requires 2930 but we're not overriding IsEip2930Enabled
like we're doing with IsEip1559Enabled
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah to be honest we should make sure that our release spec is following the spec, so have those cascades.
public record struct ValidationResult(string? Error) | ||
{ | ||
public static ValidationResult Success => new(null); | ||
public static implicit operator bool(ValidationResult result) => result.AsBool(); | ||
public static implicit operator ValidationResult(string error) => new(error); | ||
public override string ToString() => Error ?? "Success"; | ||
public bool AsBool() => Error is null; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NOTE: We have several *Result
types that could be replaced with a generic Result<E, T>
(ex. ValidationResult
, SearchResult
, RpcResult
, etc.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe but not sure, here we are using syntactic sugar with implicit conversion to bool, which allows us to treat it as a boolean value. Not sure if we can leverage that with generics easily and if it would be worth it - would have to see it.
Partially solves #7313
Changes
TxValidator
to dispatch transaction validation to appropriate sub validators.Types of changes
What types of changes does your code introduce?
Testing
Requires testing
If yes, did you write tests?
Notes on testing
All unit tests are passing.
Documentation
Requires documentation update
Requires explanation in Release Notes
Remarks
Please see the existing discussion.