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

Refactor TxValidator #7386

Merged
merged 28 commits into from
Sep 10, 2024
Merged

Refactor TxValidator #7386

merged 28 commits into from
Sep 10, 2024

Conversation

emlautarom1
Copy link
Contributor

Partially solves #7313

Changes

  • Refactor TxValidator to dispatch transaction validation to appropriate sub validators.

Types of changes

What types of changes does your code introduce?

  • Bugfix (a non-breaking change that fixes an issue)
  • New feature (a non-breaking change that adds functionality)
  • Breaking change (a change that causes existing functionality not to work as expected)
  • Optimization
  • Refactoring
  • Documentation update
  • Build-related changes
  • Other: Description

Testing

Requires testing

  • Yes
  • No

If yes, did you write tests?

  • Yes
  • No

Notes on testing

All unit tests are passing.

Documentation

Requires documentation update

  • Yes
  • No

Requires explanation in Release Notes

  • Yes
  • No

Remarks

Please see the existing discussion.

- 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
Copy link
Contributor Author

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
Copy link
Contributor Author

@emlautarom1 emlautarom1 Sep 3, 2024

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 TxTypes like IntrinsicGasTxValidator but I might be missing some context.

Copy link
Contributor

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?

Copy link
Member

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.

Copy link
Member

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.

@@ -8,21 +8,11 @@

namespace Nethermind.Optimism;

public class OptimismTxValidator : ITxValidator
public sealed class OptimismTxValidator : ITxValidator
Copy link
Contributor

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?

Copy link
Member

@LukaszRozmej LukaszRozmej left a 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

src/Nethermind/Nethermind.TxPool/ITxValidator.cs Outdated Show resolved Hide resolved
@@ -8,21 +8,11 @@

namespace Nethermind.Optimism;

public class OptimismTxValidator : ITxValidator
public sealed class OptimismTxValidator : ITxValidator
Copy link
Member

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.

@LukaszRozmej LukaszRozmej mentioned this pull request Sep 8, 2024
12 tasks
@@ -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; }
Copy link
Member

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?

Copy link
Contributor Author

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 TxTypes:

_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; }
Copy link
Member

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?

Copy link
Contributor Author

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)
Copy link
Member

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

Copy link
Contributor Author

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?

LukaszRozmej and others added 2 commits September 9, 2024 19:46
Co-authored-by: Jorge Mederos <46798594+jmederosalvarado@users.noreply.github.com>
# Conflicts:
#	src/Nethermind/Nethermind.Optimism/InitializeBlockchainOptimism.cs
Comment on lines +58 to +62
public bool IsEip1559Enabled
{
get => _isEip1559Enabled || IsEip4844Enabled;
set => _isEip1559Enabled = value;
}
Copy link
Contributor Author

@emlautarom1 emlautarom1 Sep 9, 2024

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.

Copy link
Member

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.

Comment on lines +6 to +13
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;
}
Copy link
Contributor Author

@emlautarom1 emlautarom1 Sep 9, 2024

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.)

Copy link
Member

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.

@emlautarom1 emlautarom1 merged commit 030b32f into master Sep 10, 2024
66 checks passed
@emlautarom1 emlautarom1 deleted the refactor/tx-validator branch September 10, 2024 16:11
rjnrohit pushed a commit that referenced this pull request Sep 12, 2024
Co-authored-by: Lukasz Rozmej <lukasz.rozmej@gmail.com>
Co-authored-by: Jorge Mederos <46798594+jmederosalvarado@users.noreply.github.com>
deffrian pushed a commit that referenced this pull request Oct 28, 2024
Co-authored-by: Lukasz Rozmej <lukasz.rozmej@gmail.com>
Co-authored-by: Jorge Mederos <46798594+jmederosalvarado@users.noreply.github.com>
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.

5 participants