-
Notifications
You must be signed in to change notification settings - Fork 563
Add EngineRequestGenerator tool #7266
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
base: master
Are you sure you want to change the base?
Changes from all commits
4e49901
eb20e15
53b7a71
72e6cfd
5229077
348020a
fcbeb1a
808fa0b
48eb08d
3cd6edd
a2d835a
b8ee632
a9a6c10
4fc4e24
3465a75
58507cd
deafcc8
2bc327c
51e588b
e53322e
9de9458
f66e2b4
66b9461
4074f15
5c31be9
a1217b5
7ebcb3a
3573958
d4bc0dc
75c04d8
0c679c6
8abc242
0d25cc3
edac8a4
2581028
03f6dc6
f7331be
61ca3e5
e360c9c
e386821
e8e7046
1132d10
86228e1
7c586f1
9ca2697
f1f0a32
bf02269
d446918
613e8bc
55cfd97
67e05ff
03bb3e0
57b183e
69de730
245a613
368174a
cfdec1c
4be132d
e69ed67
a415815
7a1822c
03379dd
6304416
021940d
28fb1f2
8548404
54a3fd0
7a91f7e
279c701
6fbd299
b3d7325
e014e2c
2742ba4
1e03eec
249f55c
3b62949
477e476
7dbfb66
f0e19f0
991ea78
b766605
a260038
1695aa1
c046e53
df0df15
645049b
56f6694
b83ee20
46b9e33
4b602b3
954fb9b
e9b50bf
9de7ca7
fc758db
533b6e4
5797a08
803324e
9fa5d9c
0bbb51a
f562a7b
3d96df6
a0a9712
c22b583
228e6ca
bf90198
89345fd
e5d3435
7c42e66
8c8d02a
f422984
838beeb
b3c34fd
7f6e742
d2d2b6b
e26de3e
ceb8d57
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited | ||
// SPDX-License-Identifier: LGPL-3.0-only | ||
|
||
namespace EngineRequestsGenerator; | ||
|
||
public static class BlockGasVariants | ||
{ | ||
public static long[] Variants = | ||
[ | ||
30_000_000, | ||
40_000_000, | ||
50_000_000, | ||
60_000_000, | ||
70_000_000, | ||
80_000_000, | ||
90_000_000, | ||
100_000_000, | ||
110_000_000, | ||
120_000_000, | ||
130_000_000, | ||
140_000_000, | ||
150_000_000, | ||
175_000_000, | ||
200_000_000, | ||
300_000_000, | ||
400_000_000, | ||
500_000_000, | ||
1_000_000_000 | ||
]; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited | ||
// SPDX-License-Identifier: LGPL-3.0-only | ||
|
||
using Nethermind.Core.Extensions; | ||
using Nethermind.Evm; | ||
|
||
namespace EngineRequestsGenerator; | ||
|
||
public static class ContractFactory | ||
{ | ||
public static List<byte> GenerateCodeToDeployContract(List<byte> codeToDeploy) | ||
{ | ||
List<byte> initCode = GenerateInitCode(codeToDeploy); | ||
List<byte> byteCode = new(); | ||
|
||
for (long i = 0; i < initCode.Count; i += 32) | ||
{ | ||
List<byte> currentWord = i == 0 | ||
? initCode.Slice(0, initCode.Count % 32) | ||
: initCode.Slice((int)i - 32 + initCode.Count % 32, 32); | ||
byteCode.Add((byte)(Instruction.PUSH1 + (byte)currentWord.Count - 1)); | ||
byteCode.AddRange(currentWord); | ||
|
||
// push memory offset - i | ||
byte[] memoryOffset = i.ToBigEndianByteArrayWithoutLeadingZeros(); | ||
if (memoryOffset is [0]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why not compare |
||
{ | ||
byteCode.Add((byte)Instruction.PUSH0); | ||
} | ||
else | ||
{ | ||
byteCode.Add((byte)(Instruction.PUSH1 + (byte)memoryOffset.Length - 1)); | ||
byteCode.AddRange(memoryOffset); | ||
} | ||
|
||
// save in memory | ||
byteCode.Add((byte)Instruction.MSTORE); | ||
} | ||
|
||
// push size of init code to read from memory | ||
byte[] sizeOfInitCode = initCode.Count.ToByteArray().WithoutLeadingZeros().ToArray(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ToArray() x2 |
||
byteCode.Add((byte)(Instruction.PUSH1 + (byte)sizeOfInitCode.Length - 1)); | ||
byteCode.AddRange(sizeOfInitCode); | ||
|
||
// offset in memory | ||
byteCode.Add((byte)(Instruction.PUSH1)); | ||
byteCode.AddRange(new[] { (byte)(32 - (initCode.Count % 32)) }); | ||
|
||
// 0 wei to send | ||
byteCode.Add((byte)Instruction.PUSH0); | ||
|
||
byteCode.Add((byte)Instruction.CREATE); | ||
|
||
Console.WriteLine($"size of prepared code: {byteCode.Count}"); | ||
|
||
return byteCode; | ||
} | ||
|
||
private static List<byte> GenerateInitCode(List<byte> codeToDeploy) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same stuff here |
||
{ | ||
List<byte> initCode = new(); | ||
|
||
for (long i = 0; i < codeToDeploy.Count; i += 32) | ||
{ | ||
List<byte> currentWord = i == 0 | ||
? codeToDeploy.Slice(0, codeToDeploy.Count % 32) | ||
: codeToDeploy.Slice((int)i - 32 + codeToDeploy.Count % 32, 32); | ||
|
||
initCode.Add((byte)(Instruction.PUSH1 + (byte)currentWord.Count - 1)); | ||
initCode.AddRange(currentWord); | ||
|
||
// push memory offset - i | ||
byte[] memoryOffset = i.ToBigEndianByteArrayWithoutLeadingZeros(); | ||
if (memoryOffset is [0]) | ||
{ | ||
initCode.Add((byte)Instruction.PUSH0); | ||
} | ||
else | ||
{ | ||
initCode.Add((byte)(Instruction.PUSH1 + (byte)memoryOffset.Length - 1)); | ||
initCode.AddRange(memoryOffset); | ||
} | ||
|
||
// save in memory | ||
initCode.Add((byte)Instruction.MSTORE); | ||
} | ||
|
||
// push size of memory read | ||
byte[] sizeOfCodeToDeploy = codeToDeploy.Count.ToByteArray().WithoutLeadingZeros().ToArray(); | ||
initCode.Add((byte)(Instruction.PUSH1 + (byte)sizeOfCodeToDeploy.Length - 1)); | ||
initCode.AddRange(sizeOfCodeToDeploy); | ||
|
||
// push memory offset | ||
initCode.Add((byte)(Instruction.PUSH1)); | ||
initCode.AddRange(new[] { (byte)(32 - (codeToDeploy.Count % 32)) }); | ||
|
||
// add return opcode | ||
initCode.Add((byte)(Instruction.RETURN)); | ||
|
||
return initCode; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\src\Nethermind\Nethermind.Core\Nethermind.Core.csproj" /> | ||
<ProjectReference Include="..\..\src\Nethermind\Nethermind.Merge.Plugin\Nethermind.Merge.Plugin.csproj" /> | ||
<ProjectReference Include="..\..\src\Nethermind\Nethermind.Merge.Plugin.Test\Nethermind.Merge.Plugin.Test.csproj" /> | ||
<PackageReference Include="CommandLineParser" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<None Update="benchmarks_chainspec.json"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
</ItemGroup> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<StartupObject>EngineRequestsGenerator.Program</StartupObject> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
</Project> |
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,61 @@ | ||||||||||||
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited | ||||||||||||
// SPDX-License-Identifier: LGPL-3.0-only | ||||||||||||
|
||||||||||||
using System.Reflection; | ||||||||||||
using Nethermind.Serialization.Json; | ||||||||||||
using Newtonsoft.Json; | ||||||||||||
|
||||||||||||
namespace EngineRequestsGenerator; | ||||||||||||
|
||||||||||||
public class MetadataGenerator | ||||||||||||
{ | ||||||||||||
private readonly string _outputPath; | ||||||||||||
|
||||||||||||
public MetadataGenerator(string outputPath) | ||||||||||||
{ | ||||||||||||
_outputPath = outputPath; | ||||||||||||
} | ||||||||||||
|
||||||||||||
public async Task GenerateAll() | ||||||||||||
{ | ||||||||||||
TestCase[] testCases = (TestCase[])Enum.GetValues(typeof(TestCase)); | ||||||||||||
var metadatas = new Metadata[testCases.Length]; | ||||||||||||
for (int i = 0; i < testCases.Length; ++i) | ||||||||||||
{ | ||||||||||||
metadatas[i] = GetOne(testCases[i]); | ||||||||||||
} | ||||||||||||
var str = JsonConvert.SerializeObject(metadatas); | ||||||||||||
|
||||||||||||
await File.WriteAllTextAsync($"{_outputPath}/metadata.json", str); | ||||||||||||
Comment on lines
+27
to
+29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Serialize directly to file |
||||||||||||
|
||||||||||||
} | ||||||||||||
|
||||||||||||
private Metadata GetOne(TestCase testCase) | ||||||||||||
{ | ||||||||||||
TestCaseMetadataAttribute metadataAttribute = GetTestCaseMetadata(testCase); | ||||||||||||
var metadata = new Metadata(Enum.GetName(typeof(TestCase),testCase)!, metadataAttribute.Title, metadataAttribute.Description); | ||||||||||||
return metadata; | ||||||||||||
} | ||||||||||||
|
||||||||||||
public class Metadata(string name, string title, string description) | ||||||||||||
{ | ||||||||||||
public string Name { get; set; } = name; | ||||||||||||
|
||||||||||||
public string Title { get; set; } = title; | ||||||||||||
|
||||||||||||
public string Description { get; set; } = description; | ||||||||||||
|
||||||||||||
public long[] GasUsed = BlockGasVariants.Variants; | ||||||||||||
} | ||||||||||||
|
||||||||||||
static TestCaseMetadataAttribute GetTestCaseMetadata(TestCase testCase) | ||||||||||||
{ | ||||||||||||
FieldInfo? fieldInfo = testCase.GetType().GetField(testCase.ToString()); | ||||||||||||
TestCaseMetadataAttribute[]? attributes = (TestCaseMetadataAttribute[])fieldInfo!.GetCustomAttributes(typeof(TestCaseMetadataAttribute), false); | ||||||||||||
|
||||||||||||
if (attributes == null || attributes.Length != 1) | ||||||||||||
throw new ArgumentException("Incorrect amount of attributes found"); | ||||||||||||
|
||||||||||||
return attributes[0]; | ||||||||||||
Comment on lines
+56
to
+59
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
} | ||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
using CommandLine; | ||
|
||
namespace EngineRequestsGenerator; | ||
|
||
|
||
public static class Program | ||
{ | ||
public class Options | ||
{ | ||
[Option('c', "chainspecpath", Required = false, HelpText = "Path to chainspec used to generate tests")] | ||
public string? ChainspecPath { get; set; } | ||
|
||
[Option('t', "testcase", Required = false, HelpText = "Title of the test case")] | ||
public string? TestCaseName { get; set; } | ||
|
||
[Option('o', "outputPath", Required = false, HelpText = "Output folder path")] | ||
public string? OutputPath { get; set; } | ||
|
||
[Option('m', "generateMetadataOnly", Required = false, HelpText = "Generating only metadata for test cases")] | ||
public bool GenerateMetadata { get; set; } | ||
} | ||
|
||
static async Task Main(string[] args) | ||
{ | ||
ParserResult<Options> result = Parser.Default.ParseArguments<Options>(args); | ||
if (result is Parsed<Options> options) | ||
await Run(options.Value); | ||
} | ||
|
||
private static async Task Run(Options options) | ||
{ | ||
if (!options.GenerateMetadata) | ||
{ | ||
var foundTestCase = Enum.TryParse(options.TestCaseName, out TestCase testCase); | ||
if (!foundTestCase) | ||
throw new ArgumentException($"Test case {options.TestCaseName} not found"); | ||
|
||
var testCaseGenerator = new TestCaseGenerator(options.ChainspecPath!, testCase, options.OutputPath!); | ||
await testCaseGenerator.Generate(); | ||
} | ||
|
||
if (options.GenerateMetadata) | ||
{ | ||
MetadataGenerator metadataGenerator = new(options.OutputPath!); | ||
await metadataGenerator.GenerateAll(); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"$schema": "http://json.schemastore.org/launchsettings.json", | ||
"profiles": { | ||
"EngineRequestsGenerator": { | ||
"commandName": "Project", | ||
"commandLineArgs": "-c benchmarks_chainspec.json -t Modexp215GasExpHeavy -o testcases" | ||
}, | ||
"MetadataGenerator": { | ||
"commandName": "Project", | ||
"commandLineArgs": "-m true -o testcases" | ||
} | ||
} | ||
} |
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.
Use Spans