Skip to content

Commit 7bd28c7

Browse files
emlautarom1kamilchodola
authored andcommitted
Optimism post-bedrock Legacy transaction validation (#7887)
1 parent 20a9840 commit 7bd28c7

File tree

4 files changed

+52
-18
lines changed

4 files changed

+52
-18
lines changed

src/Nethermind/Nethermind.Optimism.Test/RlpDecoderTests.cs

+33-10
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using FluentAssertions;
55
using Nethermind.Core;
6+
using Nethermind.Core.Extensions;
67
using Nethermind.Core.Test.Builders;
78
using Nethermind.Serialization.Rlp;
89
using NUnit.Framework;
@@ -11,37 +12,59 @@ namespace Nethermind.Optimism.Test;
1112

1213
public class RlpDecoderTests
1314
{
15+
private TxDecoder _decoder = null!;
16+
17+
[SetUp]
18+
public void Setup()
19+
{
20+
_decoder = TxDecoder.Instance;
21+
_decoder.RegisterDecoder(new OptimismTxDecoder<Transaction>());
22+
_decoder.RegisterDecoder(new OptimismLegacyTxDecoder());
23+
}
24+
1425
[Test]
1526
public void Can_decode_non_null_Transaction()
1627
{
17-
TxDecoder decoder = TxDecoder.Instance;
18-
decoder.RegisterDecoder(new OptimismTxDecoder<Transaction>());
19-
2028
Transaction tx = Build.A.Transaction.WithType(TxType.DepositTx).TestObject;
2129

22-
RlpStream rlpStream = new(decoder.GetLength(tx, RlpBehaviors.None));
23-
decoder.Encode(rlpStream, tx);
30+
RlpStream rlpStream = new(_decoder.GetLength(tx, RlpBehaviors.None));
31+
_decoder.Encode(rlpStream, tx);
2432
rlpStream.Reset();
2533

26-
Transaction? decodedTx = decoder.Decode(rlpStream);
34+
Transaction? decodedTx = _decoder.Decode(rlpStream);
2735

2836
decodedTx.Should().NotBeNull();
2937
}
3038

3139
[Test]
3240
public void Can_decode_non_null_Transaction_through_Rlp()
3341
{
34-
TxDecoder decoder = TxDecoder.Instance;
35-
decoder.RegisterDecoder(new OptimismTxDecoder<Transaction>());
42+
_decoder.RegisterDecoder(new OptimismTxDecoder<Transaction>());
3643

3744
Transaction tx = Build.A.Transaction.WithType(TxType.DepositTx).TestObject;
3845

39-
RlpStream rlpStream = new(decoder.GetLength(tx, RlpBehaviors.None));
40-
decoder.Encode(rlpStream, tx);
46+
RlpStream rlpStream = new(_decoder.GetLength(tx, RlpBehaviors.None));
47+
_decoder.Encode(rlpStream, tx);
4148
rlpStream.Reset();
4249

4350
Transaction? decodedTx = Rlp.Decode<Transaction?>(rlpStream);
4451

4552
decodedTx.Should().NotBeNull();
4653
}
54+
55+
[Test]
56+
public void Can_decode_Legacy_Empty_Signature()
57+
{
58+
_decoder.RegisterDecoder(new OptimismTxDecoder<Transaction>());
59+
60+
// See: https://github.com/NethermindEth/nethermind/issues/7880
61+
var hexBytes =
62+
"f901c9830571188083030d4094420000000000000000000000000000000000000780b901a4cbd4ece9000000000000000000000000420000000000000000000000000000000000001000000000000000000000000099c9fc46f92e8a1c0dec1b1747d010903e884be10000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000005711800000000000000000000000000000000000000000000000000000000000000e4662a633a000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000117274dde02bc94006185af87d78beab28ceae06000000000000000000000000117274dde02bc94006185af87d78beab28ceae06000000000000000000000000000000000000000000000000000000000c3d8b8000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000808080";
63+
var bytes = Bytes.FromHexString(hexBytes);
64+
var context = bytes.AsRlpValueContext();
65+
66+
var transaction = _decoder.Decode(ref context);
67+
68+
transaction.Should().NotBeNull();
69+
}
4770
}

src/Nethermind/Nethermind.Optimism/InitializeBlockchainOptimism.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ protected override async Task InitBlockchain()
3838
await base.InitBlockchain();
3939

4040
api.RegisterTxType<OptimismTransactionForRpc>(new OptimismTxDecoder<Transaction>(), Always.Valid);
41-
api.RegisterTxType<LegacyTransactionForRpc>(new OptimismLegacyTxDecoder(), new OptimismLegacyTxValidator());
41+
api.RegisterTxType<LegacyTransactionForRpc>(new OptimismLegacyTxDecoder(), new OptimismLegacyTxValidator(api.SpecProvider!.ChainId));
4242
}
4343

4444
protected override ITransactionProcessor CreateTransactionProcessor(CodeInfoRepository codeInfoRepository, VirtualMachine virtualMachine)

src/Nethermind/Nethermind.Optimism/OptimismLegacyTxDecoder.cs

+17-6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// SPDX-License-Identifier: LGPL-3.0-only
33

44
using System;
5+
using Nethermind.Consensus.Validators;
56
using Nethermind.Core;
67
using Nethermind.Core.Crypto;
78
using Nethermind.Core.Specs;
@@ -11,7 +12,7 @@
1112

1213
namespace Nethermind.Optimism;
1314

14-
public class OptimismLegacyTxDecoder : LegacyTxDecoder<Transaction>
15+
public sealed class OptimismLegacyTxDecoder : LegacyTxDecoder<Transaction>
1516
{
1617
protected override Signature? DecodeSignature(ulong v, ReadOnlySpan<byte> rBytes, ReadOnlySpan<byte> sBytes, Signature? fallbackSignature = null,
1718
RlpBehaviors rlpBehaviors = RlpBehaviors.None)
@@ -24,16 +25,26 @@ public class OptimismLegacyTxDecoder : LegacyTxDecoder<Transaction>
2425
}
2526
}
2627

27-
public class OptimismLegacyTxValidator : ITxValidator
28+
public sealed class OptimismLegacyTxValidator(ulong chainId) : ITxValidator
2829
{
30+
private ITxValidator _postBedrockValidator = new CompositeTxValidator([
31+
IntrinsicGasTxValidator.Instance,
32+
new LegacySignatureTxValidator(chainId),
33+
ContractSizeTxValidator.Instance,
34+
NonBlobFieldsTxValidator.Instance,
35+
NonSetCodeFieldsTxValidator.Instance
36+
]);
37+
2938
public ValidationResult IsWellFormed(Transaction transaction, IReleaseSpec releaseSpec)
3039
{
31-
// In op bedrock eip1559 activated with bedrock
32-
if (releaseSpec.IsEip1559Enabled)
40+
// In Optimism, EIP1559 is activated in Bedrock
41+
var isPreBedrock = !releaseSpec.IsEip1559Enabled;
42+
if (isPreBedrock)
3343
{
34-
return transaction.Signature is null ? new ValidationResult("Empty signature") : ValidationResult.Success;
44+
// Pre-Bedrock we peform no validation at all
45+
return ValidationResult.Success;
3546
}
3647

37-
return ValidationResult.Success;
48+
return _postBedrockValidator.IsWellFormed(transaction, releaseSpec);
3849
}
3950
}

src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public void InitTxTypesAndRlpDecoders(INethermindApi api)
8686
if (ShouldRunSteps(api))
8787
{
8888
api.RegisterTxType<OptimismTransactionForRpc>(new OptimismTxDecoder<Transaction>(), Always.Valid);
89-
api.RegisterTxType<LegacyTransactionForRpc>(new OptimismLegacyTxDecoder(), new OptimismLegacyTxValidator());
89+
api.RegisterTxType<LegacyTransactionForRpc>(new OptimismLegacyTxDecoder(), new OptimismLegacyTxValidator(api.SpecProvider!.ChainId));
9090
Rlp.RegisterDecoders(typeof(OptimismReceiptMessageDecoder).Assembly, true);
9191
}
9292
}

0 commit comments

Comments
 (0)