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

Eip 3607 #3280

Merged
merged 24 commits into from
Oct 19, 2021
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
1ec576b
eip-3607 changes
kjazgar Jul 26, 2021
ccfbec1
eip3607 changes
kjazgar Aug 3, 2021
5a7342b
cosmetic changes
kjazgar Aug 3, 2021
a36d38b
Added description and made stylistic changes.
kjazgar Aug 9, 2021
15b4a43
Simplifications and refactoring
LukaszRozmej Aug 24, 2021
8e33668
Merge remote-tracking branch 'origin/master' into eip_3607
LukaszRozmej Aug 24, 2021
780c713
Refactoring of TxPool tests.
kjazgar Aug 25, 2021
2ff91e3
Merge remote-tracking branch 'origin/master' into eip_3607
kjazgar Aug 25, 2021
2508e8a
Added check if eip3607 is enabled.
kjazgar Aug 26, 2021
b6c69fc
refactor BlockProcessor.BlockProductionTransactionPicker.cs
LukaszRozmej Sep 2, 2021
1770b00
simplify tests
LukaszRozmej Sep 2, 2021
e9e0ce6
fix
LukaszRozmej Sep 2, 2021
b8a53ae
Merge remote-tracking branch 'origin/master' into eip_3607
LukaszRozmej Sep 2, 2021
a51ba6c
Load Eip3607Transition from json correctly
LukaszRozmej Sep 2, 2021
b864150
Enable 3607 by default everywhere
LukaszRozmej Oct 13, 2021
e522023
Add 3607 check on bundle transactions
LukaszRozmej Oct 13, 2021
56e14d4
fix tests
LukaszRozmej Oct 13, 2021
7163c76
Merge remote-tracking branch 'origin/master' into eip_3607
LukaszRozmej Oct 13, 2021
460e6f8
Fix BaseFee tests
LukaszRozmej Oct 15, 2021
cc8bea6
Merge branch 'master' into eip_3607
LukaszRozmej Oct 18, 2021
62af938
refactoring
LukaszRozmej Oct 19, 2021
3c4e9e2
fixes
LukaszRozmej Oct 19, 2021
71f1149
fix rpc trace
LukaszRozmej Oct 19, 2021
a9015b6
proper fix
LukaszRozmej Oct 19, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
"eip1344Transition": "0x0",
"eip1706Transition": "0x0",
"eip1884Transition": "0x0",
"eip2028Transition": "0x0"
"eip2028Transition": "0x0",
"eip3607Transition": "0xFFFFFFFFFFFF"
},
"genesis": {
"seal": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,11 @@ private async Task<ScenarioBuilder> CreateTestBlockchainAsync(long gasLimit)
SingleReleaseSpecProvider spec = new(
new ReleaseSpec()
{
IsEip1559Enabled = _eip1559Enabled, Eip1559TransitionBlock = _eip1559TransitionBlock
IsEip1559Enabled = _eip1559Enabled,
Eip1559TransitionBlock = _eip1559TransitionBlock,
IsEip155Enabled = true
}, 1);
BlockBuilder blockBuilder = Core.Test.Builders.Build.A.Block.Genesis.WithGasLimit(gasLimit);
BlockBuilder blockBuilder = Build.A.Block.Genesis.WithGasLimit(gasLimit);
_testRpcBlockchain = await TestRpcBlockchain.ForTest(SealEngineType.NethDev)
.WithGenesisBlockBuilder(blockBuilder)
.Build(spec);
Expand Down Expand Up @@ -132,7 +134,8 @@ private async Task<ScenarioBuilder> SendTransactionAsync(long gasLimit, UInt256
tx.Nonce = _currentNonce;
++_currentNonce;

await _testRpcBlockchain.TxSender.SendTransaction(tx, TxHandlingOptions.None);
var (_, result) = await _testRpcBlockchain.TxSender.SendTransaction(tx, TxHandlingOptions.None);
Assert.AreEqual(AddTxResult.Added, result);
return this;
}

Expand Down Expand Up @@ -302,7 +305,6 @@ public async Task BaseFee_should_decrease_when_we_send_transactions_below_gas_ta
public async Task BaseFee_should_not_change_when_we_send_transactions_equal_gas_target()
{
long gasTarget = 3000000;
long gasLimit = Eip1559Constants.ElasticityMultiplier * gasTarget;
BaseFeeTestScenario.ScenarioBuilder scenario = BaseFeeTestScenario.GoesLikeThis()
.WithEip1559TransitionBlock(6)
.CreateTestBlockchain(gasTarget)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
using Nethermind.Evm;
using Nethermind.Int256;
using Nethermind.Logging;
using Nethermind.Specs;
using Nethermind.State;

namespace Nethermind.Blockchain.Processing
Expand Down Expand Up @@ -67,14 +68,20 @@ public AddingTxEventArgs CanAddTransaction(Block block, Transaction currentTx, I
return args.Set(TxAction.Skip, "Transaction already in block");
}

IReleaseSpec spec = _specProvider.GetSpec(block.Number);
if (stateProvider.InvalidContractSender(spec, currentTx.SenderAddress))
{
return args.Set(TxAction.Skip, $"Sender is contract");
}

UInt256 expectedNonce = stateProvider.GetNonce(currentTx.SenderAddress);
if (expectedNonce != currentTx.Nonce)
{
return args.Set(TxAction.Skip, $"Invalid nonce - expected {expectedNonce}");
}

UInt256 balance = stateProvider.GetBalance(currentTx.SenderAddress);
if (!HasEnoughFounds(currentTx, balance, args, block))
if (!HasEnoughFounds(currentTx, balance, args, block, spec))
{
return args;
}
Expand All @@ -83,9 +90,8 @@ public AddingTxEventArgs CanAddTransaction(Block block, Transaction currentTx, I
return args;
}

private bool HasEnoughFounds(Transaction transaction, UInt256 senderBalance, AddingTxEventArgs e, Block block)
private bool HasEnoughFounds(Transaction transaction, UInt256 senderBalance, AddingTxEventArgs e, Block block, IReleaseSpec releaseSpec)
{
IReleaseSpec releaseSpec = _specProvider.GetSpec(block.Number);
bool eip1559Enabled = releaseSpec.IsEip1559Enabled;
UInt256 transactionPotentialCost = transaction.CalculateTransactionPotentialCost(eip1559Enabled, block.BaseFeePerGas);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,14 @@ public TxPriorityContract(
}

public Address[] GetSendersWhitelist(BlockHeader parentHeader) =>
Constant.Call<Address[]>(new CallInfo(parentHeader, nameof(GetSendersWhitelist), ContractAddress) {MissingContractResult = MissingSenderWhitelistResult});
Constant.Call<Address[]>(new CallInfo(parentHeader, nameof(GetSendersWhitelist), Address.SystemUser) {MissingContractResult = MissingSenderWhitelistResult});

public Destination[] GetMinGasPrices(BlockHeader parentHeader) =>
Constant.Call<DestinationTuple[]>(new CallInfo(parentHeader, nameof(GetMinGasPrices), ContractAddress) {MissingContractResult = MissingPrioritiesResult})
Constant.Call<DestinationTuple[]>(new CallInfo(parentHeader, nameof(GetMinGasPrices), Address.SystemUser) {MissingContractResult = MissingPrioritiesResult})
.Select(x => Destination.FromAbiTuple(x, parentHeader.Number)).ToArray();

public Destination[] GetPriorities(BlockHeader parentHeader) =>
Constant.Call<DestinationTuple[]>(new CallInfo(parentHeader, nameof(GetPriorities), ContractAddress) {MissingContractResult = MissingPrioritiesResult})
Constant.Call<DestinationTuple[]>(new CallInfo(parentHeader, nameof(GetPriorities), Address.SystemUser) {MissingContractResult = MissingPrioritiesResult})
.Select(x => Destination.FromAbiTuple(x, parentHeader.Number)).ToArray();

public IEnumerable<Destination> PrioritySet(BlockHeader blockHeader, TxReceipt[] receipts)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
using Nethermind.State.Repositories;
using Nethermind.Db.Blooms;
using Nethermind.Evm.TransactionProcessing;
using Nethermind.Specs.Test;
using Nethermind.Trie;
using Nethermind.Trie.Pruning;
using Nethermind.TxPool;
Expand Down Expand Up @@ -112,11 +113,11 @@ protected TestBlockchain()

public static TransactionBuilder<Transaction> BuildSimpleTransaction => Builders.Build.A.Transaction.SignedAndResolved(TestItem.PrivateKeyA).To(AccountB);

protected virtual async Task<TestBlockchain> Build(ISpecProvider specProvider = null, UInt256? initialValues = null)
protected virtual async Task<TestBlockchain> Build(ISpecProvider? specProvider = null, UInt256? initialValues = null)
{
Timestamper = new ManualTimestamper(new DateTime(2020, 2, 15, 12, 50, 30, DateTimeKind.Utc));
JsonSerializer = new EthereumJsonSerializer();
SpecProvider = specProvider ?? MainnetSpecProvider.Instance;
SpecProvider = new OverridableSpecProvider(specProvider ?? MainnetSpecProvider.Instance, s => new OverridableReleaseSpec(s) { IsEip3607Enabled = false });
EthereumEcdsa = new EthereumEcdsa(ChainId.Mainnet, LogManager);
DbProvider = await TestMemDbProvider.InitAsync();
TrieStore = new TrieStore(StateDb.Innermost, LogManager);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<ProjectReference Include="..\Nethermind.Blockchain\Nethermind.Blockchain.csproj" />
<ProjectReference Include="..\Nethermind.Core\Nethermind.Core.csproj" />
<ProjectReference Include="..\Nethermind.Network\Nethermind.Network.csproj" />
<ProjectReference Include="..\Nethermind.Specs.Test\Nethermind.Specs.Test.csproj" />
</ItemGroup>
<ItemGroup>
<Content Include="TestRopstenBlocks\*.*">
Expand Down
31 changes: 31 additions & 0 deletions src/Nethermind/Nethermind.Core/AccountStateProviderExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) 2021 Demerzel Solutions Limited
// This file is part of the Nethermind library.
//
// The Nethermind library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The Nethermind library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the Nethermind. If not, see <http://www.gnu.org/licenses/>.
//

using Nethermind.Core.Crypto;
using Nethermind.Core.Specs;

namespace Nethermind.Core
{
public static class AccountStateProviderExtensions
{
public static bool HasCode(this IAccountStateProvider stateProvider, Address address) =>
stateProvider.GetAccount(address).HasCode;

public static bool InvalidContractSender(this IAccountStateProvider stateProvider, IReleaseSpec spec, Address address) =>
spec.IsEip3607Enabled && stateProvider.HasCode(address);
}
}
4 changes: 3 additions & 1 deletion src/Nethermind/Nethermind.Core/IAccountStateProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@
// along with the Nethermind. If not, see <http://www.gnu.org/licenses/>.
//

using Nethermind.Core.Crypto;

namespace Nethermind.Core
{
public interface IAccountStateProvider
{
Account GetAccount(Address address);
Account GetAccount(Address address);
}
}
9 changes: 7 additions & 2 deletions src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,12 +244,17 @@ public interface IReleaseSpec
/// Reject new contracts starting with the 0xEF byte
/// </summary>
bool IsEip3541Enabled { get; }


/// <summary>
/// Reject transactions where senders have non-empty code hash
/// </summary>
bool IsEip3607Enabled { get; }

/// <summary>
/// Upgrade consensus to Proof-of-Stake
/// </summary>
bool IsEip3675Enabled { get; }

/// <summary>
/// Should transactions be validated against chainId.
/// </summary>
Expand Down
19 changes: 16 additions & 3 deletions src/Nethermind/Nethermind.Evm.Test/Tracing/ProofTxTracerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,33 @@ public void Can_trace_sender_recipient_miner()
}

[Test]
public void Can_trace_sender_recipient_miner_when_all_are_same()
public void Can_trace_sender_recipient_miner_when_miner_and_sender_are_same()
{
byte[] code = Prepare.EvmCode
.PushData(SampleHexData1)
.Done;

SenderRecipientAndMiner addresses = new();
addresses.RecipientKey = SenderKey;
addresses.MinerKey = SenderKey;
(ProofTxTracer trace, _, _) = ExecuteAndTraceProofCall(addresses, code);
Assert.AreEqual(1, trace.Accounts.Count, "count");
Assert.AreEqual(2, trace.Accounts.Count, "count");
Assert.True(trace.Accounts.Contains(Sender));
}

[Test]
public void Can_trace_sender_recipient_miner_when_miner_and_recipient_are_same()
{
byte[] code = Prepare.EvmCode
.PushData(SampleHexData1)
.Done;

SenderRecipientAndMiner addresses = new();
addresses.MinerKey = addresses.RecipientKey;
(ProofTxTracer trace, _, _) = ExecuteAndTraceProofCall(addresses, code);
Assert.AreEqual(2, trace.Accounts.Count, "count");
Assert.True(trace.Accounts.Contains(Sender));
}

[Test]
public void Can_trace_touch_only_null_accounts()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,13 @@ private void Execute(Transaction transaction, BlockHeader block, ITxTracer txTra
return;
}

if (spec.IsEip3607Enabled && _stateProvider.HasCode(caller))
{
TraceLogInvalidTx(transaction, "SENDER_IS_CONTRACT");
QuickFail(transaction, block, txTracer, eip658NotEnabled, "sender has deployed code");
return;
}

long intrinsicGas = IntrinsicGasCalculator.Calculate(transaction, spec);
if (_logger.IsTrace) _logger.Trace($"Intrinsic gas calculated for {transaction.Hash}: " + intrinsicGas);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,13 @@ public Builder<T> WithGasPriceOracle(IGasPriceOracle gasPriceOracle)
return this;
}

public async Task<T> Build(ISpecProvider specProvider = null, UInt256? initialValues = null)
public async Task<T> Build(ISpecProvider? specProvider = null, UInt256? initialValues = null)
{
return (T)(await _blockchain.Build(specProvider, initialValues));
}
}

protected override async Task<TestBlockchain> Build(ISpecProvider specProvider = null, UInt256? initialValues = null)
protected override async Task<TestBlockchain> Build(ISpecProvider? specProvider = null, UInt256? initialValues = null)
{
BloomStorage bloomStorage = new(new BloomConfig(), new MemDb(), new InMemoryDictionaryFileStoreFactory());
specProvider ??= new TestSpecProvider(Berlin.Instance) {ChainId = ChainId.Mainnet};
Expand Down
7 changes: 6 additions & 1 deletion src/Nethermind/Nethermind.Mev.Test/TestBundlePool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public TestBundlePool(IBlockTree blockTree,
ISpecProvider specProvider,
IMevConfig mevConfig,
ILogManager logManager)
: base(blockTree, simulator, timestamper, txValidator, specProvider, mevConfig, logManager)
: base(blockTree, simulator, timestamper, txValidator, specProvider, mevConfig, new MockProvider(), logManager)
{
}

Expand Down Expand Up @@ -83,4 +83,9 @@ public TestBundlePool(IBlockTree blockTree,
return null;
}
}

public class MockProvider : IAccountStateProvider
{
public Account GetAccount(Address address) => new Account(0);
}
}
1 change: 1 addition & 0 deletions src/Nethermind/Nethermind.Mev/MevPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ private BundlePool BundlePool
getFromApi.TxValidator!,
getFromApi.SpecProvider!,
_mevConfig,
getFromApi.ChainHeadStateProvider!,
getFromApi.LogManager);
}

Expand Down
13 changes: 12 additions & 1 deletion src/Nethermind/Nethermind.Mev/Source/BundlePool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public class BundlePool : IBundlePool, ISimulatedBundleSource, IDisposable
private readonly ITimestamper _timestamper;
private readonly ITxValidator _txValidator;
private readonly IMevConfig _mevConfig;
private readonly IAccountStateProvider _stateProvider;
private readonly ISpecProvider _specProvider;
private readonly IBlockTree _blockTree;
private readonly IBundleSimulator _simulator;
Expand All @@ -68,11 +69,13 @@ public BundlePool(
ITxValidator txValidator,
ISpecProvider specProvider,
IMevConfig mevConfig,
IAccountStateProvider stateProvider,
ILogManager logManager)
{
_timestamper = timestamper;
_txValidator = txValidator;
_mevConfig = mevConfig;
_stateProvider = stateProvider;
_specProvider = specProvider;
_blockTree = blockTree;
_simulator = simulator;
Expand Down Expand Up @@ -175,8 +178,16 @@ private bool ValidateBundle(MevBundle bundle)
IReleaseSpec spec = _specProvider.GetSpec(bundle.BlockNumber);
for (int i = 0; i < bundle.Transactions.Count; i++)
{
if (!_txValidator.IsWellFormed(bundle.Transactions[i], spec))
BundleTransaction tx = bundle.Transactions[i];

if (!_txValidator.IsWellFormed(tx, spec))
{
return false;
}

if (_stateProvider.InvalidContractSender(spec, tx.SenderAddress!))
{
if (_logger.IsDebug) _logger.Debug($"Bundle rejected, because transaction {tx.Hash} sender {tx.SenderAddress} is contract.");
return false;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public override void WriteJson(JsonWriter writer, BigInteger? value, JsonSeriali

public override BigInteger? ReadJson(JsonReader reader, Type objectType, BigInteger? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
if (reader.TokenType == JsonToken.Null || reader.Value is null)
{
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public override void WriteJson(JsonWriter writer, long? value, JsonSerializer se

public override long? ReadJson(JsonReader reader, Type objectType, long? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
if (reader.TokenType == JsonToken.Null || reader.Value is null)
{
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public override void WriteJson(JsonWriter writer, UInt256? value, JsonSerializer

public override UInt256? ReadJson(JsonReader reader, Type objectType, UInt256? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
if (reader.TokenType == JsonToken.Null || reader.Value is null)
{
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,18 @@

namespace Nethermind.Specs.Test
{
/// <summary>Only for testing purposes.
// If we want to override only a few properties for tests based on different releases spec we can use this class.</summary>
/// <summary>
/// Only for testing purposes.
/// If we want to override only a few properties for tests based on different releases spec we can use this class.
/// </summary>
public class OverridableReleaseSpec : IReleaseSpec
{
private readonly IReleaseSpec _spec;

public OverridableReleaseSpec(IReleaseSpec spec)
{
_spec = spec;
IsEip3607Enabled = _spec.IsEip3607Enabled;
}

public string Name => "OverridableReleaseSpec";
Expand Down Expand Up @@ -123,6 +126,7 @@ public OverridableReleaseSpec(IReleaseSpec spec)
public bool IsEip3529Enabled => _spec.IsEip3529Enabled;

public bool IsEip3541Enabled => _spec.IsEip3541Enabled;
public bool IsEip3607Enabled { get; set; }
public bool IsEip3675Enabled => _spec.IsEip3675Enabled;

public bool IsEip158IgnoredAccount(Address address)
Expand Down
Loading