Skip to content

Commit 0313868

Browse files
committed
Add compilation id, source contents, and language to ethdebug resource output
1 parent aa880e7 commit 0313868

File tree

15 files changed

+195
-43
lines changed

15 files changed

+195
-43
lines changed

libevmasm/Ethdebug.cpp

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -148,22 +148,3 @@ Json ethdebug::program(std::string_view _name, unsigned _sourceID, Assembly cons
148148
.instructions = programInstructions(_assembly, _linkerObject, _sourceID)
149149
};
150150
}
151-
152-
Json ethdebug::resources(std::vector<std::string> const& _sources, std::string const& _version)
153-
{
154-
Json sources = Json::array();
155-
for (size_t id = 0; id < _sources.size(); ++id)
156-
{
157-
Json source = Json::object();
158-
source["id"] = id;
159-
source["path"] = _sources[id];
160-
sources.push_back(source);
161-
}
162-
Json result = Json::object();
163-
result["compilation"] = Json::object();
164-
result["compilation"]["compiler"] = Json::object();
165-
result["compilation"]["compiler"]["name"] = "solc";
166-
result["compilation"]["compiler"]["version"] = _version;
167-
result["compilation"]["sources"] = sources;
168-
return result;
169-
}

libevmasm/Ethdebug.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,4 @@ namespace solidity::evmasm::ethdebug
2929
// returns ethdebug/format/program.
3030
Json program(std::string_view _name, unsigned _sourceID, Assembly const& _assembly, LinkerObject const& _linkerObject);
3131

32-
// returns ethdebug/format/info/resources
33-
Json resources(std::vector<std::string> const& _sources, std::string const& _version);
34-
3532
} // namespace solidity::evmasm::ethdebug

libevmasm/EthdebugSchema.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,23 @@ void schema::materials::to_json(Json& _json, SourceRange::Range const& _range)
5858
_json["offset"] = _range.offset;
5959
}
6060

61+
void schema::materials::to_json(Json& _json, Source const& _source)
62+
{
63+
_json["id"] = _source.id;
64+
_json["path"] = _source.path;
65+
_json["contents"] = _source.contents;
66+
if (_source.encoding)
67+
_json["encoding"] = *_source.encoding;
68+
_json["language"] = _source.language;
69+
}
70+
71+
void schema::materials::to_json(Json& _json, Compilation const& _compilation)
72+
{
73+
_json["id"] = _compilation.id;
74+
_json["compiler"]["name"] = _compilation.compiler.name;
75+
_json["compiler"]["version"] = _compilation.compiler.version;
76+
_json["sources"] = _compilation.sources;
77+
}
6178

6279
void schema::materials::to_json(Json& _json, SourceRange const& _sourceRange)
6380
{
@@ -73,6 +90,13 @@ void schema::to_json(Json& _json, Program::Contract const& _contract)
7390
_json["definition"] = _contract.definition;
7491
}
7592

93+
void schema::info::to_json(Json& _json, Resources const& _resources)
94+
{
95+
if (_resources.compilation)
96+
_json["compilation"] = *_resources.compilation;
97+
}
98+
99+
76100
void schema::program::to_json(Json& _json, Context::Variable const& _contextVariable)
77101
{
78102
auto const numProperties =

libevmasm/EthdebugSchema.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,35 @@ struct SourceRange
8888
std::optional<Range> range;
8989
};
9090

91+
struct Source
92+
{
93+
ID id;
94+
std::string path;
95+
std::string contents;
96+
std::optional<std::string> encoding;
97+
std::string language;
98+
};
99+
100+
struct Compilation
101+
{
102+
struct Compiler
103+
{
104+
std::string name;
105+
std::string version;
106+
};
107+
ID id;
108+
Compiler compiler;
109+
std::vector<Source> sources;
110+
};
111+
112+
}
113+
114+
namespace info
115+
{
116+
struct Resources
117+
{
118+
std::optional<materials::Compilation> compilation;
119+
};
91120
}
92121

93122
namespace program
@@ -155,6 +184,13 @@ void to_json(Json& _json, ID const& _id);
155184
void to_json(Json& _json, Reference const& _source);
156185
void to_json(Json& _json, SourceRange::Range const& _range);
157186
void to_json(Json& _json, SourceRange const& _sourceRange);
187+
void to_json(Json& _json, Source const& _source);
188+
void to_json(Json& _json, Compilation const& _compilation);
189+
}
190+
191+
namespace info
192+
{
193+
void to_json(Json& _json, Resources const& _resources);
158194
}
159195

160196
namespace program

libsolidity/interface/CompilerStack.cpp

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
#include <libsolutil/FunctionSelector.h>
8686

8787
#include <libevmasm/Ethdebug.h>
88+
#include <libevmasm/EthdebugSchema.h>
8889

8990
#include <boost/algorithm/string/replace.hpp>
9091

@@ -1196,7 +1197,38 @@ Json CompilerStack::ethdebug() const
11961197
{
11971198
solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful.");
11981199
solAssert(!m_contracts.empty());
1199-
return evmasm::ethdebug::resources(sourceNames(), VersionString);
1200+
1201+
std::vector<std::string> const paths = sourceNames();
1202+
1203+
std::vector<evmasm::ethdebug::schema::materials::Source> sources;
1204+
sources.reserve(paths.size());
1205+
1206+
for (auto const& sourcePath: paths)
1207+
sources.push_back(
1208+
evmasm::ethdebug::schema::materials::Source{
1209+
.id = {sourceIndices()[sourcePath]},
1210+
.path = sourcePath,
1211+
.contents = source(sourcePath).charStream->source(),
1212+
.encoding = std::nullopt,
1213+
.language = "Solidity"
1214+
}
1215+
);
1216+
1217+
std::stringstream concatenatedMetadata;
1218+
for (auto const& contract: m_contracts | ranges::views::values)
1219+
concatenatedMetadata << metadata(contract);
1220+
evmasm::ethdebug::schema::info::Resources resources {
1221+
.compilation = evmasm::ethdebug::schema::materials::Compilation {
1222+
.id = {util::toHex(util::ipfsHash(concatenatedMetadata.str()), util::HexPrefix::Add)},
1223+
.compiler = evmasm::ethdebug::schema::materials::Compilation::Compiler {
1224+
.name = "solc",
1225+
.version = VersionString
1226+
},
1227+
.sources = sources
1228+
}
1229+
};
1230+
1231+
return resources;
12001232
}
12011233

12021234
Json CompilerStack::ethdebug(std::string const& _contractName) const
@@ -1931,7 +1963,15 @@ bytes CompilerStack::createCBORMetadata(Contract const& _contract, bool _forIR)
19311963
_contract.contract->sourceUnit().annotation().experimentalFeatures
19321964
);
19331965

1934-
std::string meta = (_forIR == m_viaIR ? metadata(_contract) : createMetadata(_contract, _forIR));
1966+
std::string otherMeta;
1967+
std::string_view meta;
1968+
if (_forIR == m_viaIR)
1969+
meta = metadata(_contract);
1970+
else
1971+
{
1972+
otherMeta = createMetadata(_contract, _forIR);
1973+
meta = otherMeta;
1974+
}
19351975

19361976
MetadataCBOREncoder encoder;
19371977

libsolidity/interface/StandardCompiler.cpp

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,15 @@
3737

3838
#include <liblangutil/SourceReferenceFormatter.h>
3939

40+
#include <libsolutil/CommonData.h>
41+
#include <libsolutil/IpfsHash.h>
4042
#include <libsolutil/JSON.h>
4143
#include <libsolutil/Keccak256.h>
42-
#include <libsolutil/CommonData.h>
4344

4445
#include <boost/algorithm/string/predicate.hpp>
4546

4647
#include <algorithm>
48+
#include <libevmasm/EthdebugSchema.h>
4749
#include <optional>
4850

4951
using namespace solidity;
@@ -1637,7 +1639,7 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu
16371639
}
16381640

16391641

1640-
Json StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings)
1642+
Json StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings, Json const& _rawInput)
16411643
{
16421644
solAssert(_inputsAndSettings.jsonSources.empty());
16431645

@@ -1787,7 +1789,27 @@ Json StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings)
17871789
output["contracts"][sourceName][contractName]["yulCFGJson"] = stack.cfgJson();
17881790

17891791
if (isEthdebugRequested(_inputsAndSettings.outputSelection))
1790-
output["ethdebug"] = evmasm::ethdebug::resources({sourceName}, VersionString);
1792+
{
1793+
std::string const id = util::toHex(ipfsHash(jsonCompactPrint(jsonCompactPrint(_rawInput) + jsonCompactPrint(_inputsAndSettings.sources))), HexPrefix::Add);
1794+
output["ethdebug"] = evmasm::ethdebug::schema::info::Resources {
1795+
.compilation = evmasm::ethdebug::schema::materials::Compilation {
1796+
.id = {id},
1797+
.compiler = evmasm::ethdebug::schema::materials::Compilation::Compiler{
1798+
.name = "solc",
1799+
.version = VersionString
1800+
},
1801+
.sources = {
1802+
evmasm::ethdebug::schema::materials::Source {
1803+
.id = evmasm::ethdebug::schema::materials::ID{std::uint64_t{0}},
1804+
.path = sourceName,
1805+
.contents = sourceContents,
1806+
.encoding = std::nullopt,
1807+
.language = "Yul"
1808+
}
1809+
}
1810+
}
1811+
};
1812+
}
17911813

17921814
return output;
17931815
}
@@ -1805,7 +1827,7 @@ Json StandardCompiler::compile(Json const& _input) noexcept
18051827
if (settings.language == "Solidity")
18061828
return compileSolidity(std::move(settings));
18071829
else if (settings.language == "Yul")
1808-
return compileYul(std::move(settings));
1830+
return compileYul(std::move(settings), _input);
18091831
else if (settings.language == "SolidityAST")
18101832
return compileSolidity(std::move(settings));
18111833
else if (settings.language == "EVMAssembly")

libsolidity/interface/StandardCompiler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class StandardCompiler
9898
std::map<std::string, Json> parseAstFromInput(StringMap const& _sources);
9999
Json importEVMAssembly(InputsAndSettings _inputsAndSettings);
100100
Json compileSolidity(InputsAndSettings _inputsAndSettings);
101-
Json compileYul(InputsAndSettings _inputsAndSettings);
101+
Json compileYul(InputsAndSettings _inputsAndSettings, Json const& _rawInput);
102102

103103
ReadCallback::Callback m_readFile;
104104

solc/CommandLineInterface.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include <libyul/YulStack.h>
4545

4646
#include <libevmasm/Ethdebug.h>
47+
#include <libevmasm/EthdebugSchema.h>
4748
#include <libevmasm/Disassemble.h>
4849

4950
#include <liblangutil/Exceptions.h>
@@ -1359,8 +1360,25 @@ void CommandLineInterface::assembleYul(yul::YulStack::Language _language, yul::Y
13591360
{
13601361
sout() << "======= Debug Data (ethdebug/format/info/resources) =======" << std::endl;
13611362
sout() << util::jsonPrint(
1362-
evmasm::ethdebug::resources({{sourceUnitName}}, VersionString),
1363-
m_options.formatting.json
1363+
evmasm::ethdebug::schema::info::Resources{
1364+
.compilation = evmasm::ethdebug::schema::materials::Compilation {
1365+
.id = {""},
1366+
.compiler = evmasm::ethdebug::schema::materials::Compilation::Compiler {
1367+
.name = "solc",
1368+
.version = VersionString
1369+
},
1370+
.sources = {
1371+
evmasm::ethdebug::schema::materials::Source {
1372+
.id = evmasm::ethdebug::schema::materials::ID{std::uint64_t{0}},
1373+
.path = sourceUnitName,
1374+
.contents = yulSource,
1375+
.encoding = std::nullopt,
1376+
.language = "Yul"
1377+
}
1378+
}
1379+
}
1380+
},
1381+
m_options.formatting.json
13641382
) << std::endl;
13651383
}
13661384

test/cmdlineTests/ethdebug_eof_container_osaka/output

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
"name": "solc",
66
"version": "<VERSION REMOVED>"
77
},
8+
"id": "0x1220a5451e57fefae301cb773787fc38d855d065067f1d80a2cf38ea4e8117f914f8",
89
"sources": [
910
{
11+
"contents": "// SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\n\ncontract C {\n function f() public {}\n}\n",
1012
"id": 0,
13+
"language": "Solidity",
1114
"path": "input.sol"
1215
}
1316
]

test/cmdlineTests/ethdebug_on_abstract/output

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
"name": "solc",
66
"version": "<VERSION REMOVED>"
77
},
8+
"id": "0x1220f18bade7c9fe1910e3cfe817d60dd1d42d85760d009fe087c91aac1aced8ed66",
89
"sources": [
910
{
11+
"contents": "// SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\n\nabstract contract C {\n function f() public virtual returns (bytes32);\n}\n",
1012
"id": 0,
13+
"language": "Solidity",
1114
"path": "input.sol"
1215
}
1316
]

test/cmdlineTests/ethdebug_on_interface/output

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
"name": "solc",
66
"version": "<VERSION REMOVED>"
77
},
8+
"id": "0x1220e2276c1de81ce47e074f4113acf7edc8160f0ac86ce866411800df43be570a94",
89
"sources": [
910
{
11+
"contents": "// SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\n\ninterface C {\n function f() external;\n}\n",
1012
"id": 0,
13+
"language": "Solidity",
1114
"path": "input.sol"
1215
}
1316
]

test/cmdlineTests/standard_output_debuginfo_ethdebug_with_interfaces_and_abstracts/output.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,30 @@
3131
"name": "solc",
3232
"version": "<VERSION REMOVED>"
3333
},
34+
"id": "0x1220c96176b836fdd259516a205e7c0ca275f5fe488c02adfe5a324380bdaef43da6",
3435
"sources": [
3536
{
37+
"contents": "// SPDX-License-Identifier: GPL-2.0
38+
pragma solidity >=0.0;
39+
40+
abstract contract C {
41+
function f() public virtual returns (bytes32);
42+
}
43+
",
3644
"id": 0,
45+
"language": "Solidity",
3746
"path": "a.sol"
3847
},
3948
{
49+
"contents": "// SPDX-License-Identifier: GPL-2.0
50+
pragma solidity >=0.0;
51+
52+
interface C {
53+
function f() external;
54+
}
55+
",
4056
"id": 1,
57+
"language": "Solidity",
4158
"path": "b.sol"
4259
}
4360
]

test/cmdlineTests/standard_yul_ethdebug_assign_immutable/output.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,18 @@
116116
"name": "solc",
117117
"version": "<VERSION REMOVED>"
118118
},
119+
"id": "0x1220567311cdfa80a7fa7e1849f45ddee044787d6bf880874638097ce6c9cc8a22b4",
119120
"sources": [
120121
{
122+
"contents": "object \"a\" {
123+
code {
124+
{
125+
setimmutable(0, \"long___name___that___definitely___exceeds___the___thirty___two___byte___limit\", 0x1234567890123456789012345678901234567890)
126+
}
127+
}
128+
}",
121129
"id": 0,
130+
"language": "Yul",
122131
"path": "C"
123132
}
124133
]

test/ethdebugSchemaTests/test_ethdebug_schema_conformity.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,14 @@ def test_program_schema(
4949
source_output = contract_output[source]
5050
ethdebug_data = get_nested_value(source_output, *(output_selection.split(".")))
5151
validator.validate(ethdebug_data)
52+
53+
def test_resource_schema(
54+
ethdebug_schema_repository,
55+
solc_output
56+
):
57+
validator = jsonschema.Draft202012Validator(
58+
schema={"$ref": "schema:ethdebug/format/info/resources"},
59+
registry=ethdebug_schema_repository
60+
)
61+
assert "ethdebug" in solc_output
62+
validator.validate(solc_output["ethdebug"])

0 commit comments

Comments
 (0)