Output experimental flag in metadata only for risky features

This commit is contained in:
Alex Beregszaszi 2017-08-10 17:16:55 +01:00
parent 4d82d4f57a
commit 2d1bab0de8
2 changed files with 28 additions and 9 deletions

View File

@ -632,6 +632,17 @@ string CompilerStack::absolutePath(string const& _path, string const& _reference
return result.generic_string(); return result.generic_string();
} }
namespace
{
bool onlySafeExperimentalFeaturesActivated(set<ExperimentalFeature> const& features)
{
for (auto const feature: features)
if (!ExperimentalFeatureOnlyAnalysis.count(feature))
return false;
return true;
}
}
void CompilerStack::compileContract( void CompilerStack::compileContract(
ContractDefinition const& _contract, ContractDefinition const& _contract,
map<ContractDefinition const*, eth::Assembly const*>& _compiledContracts map<ContractDefinition const*, eth::Assembly const*>& _compiledContracts
@ -649,16 +660,23 @@ void CompilerStack::compileContract(
shared_ptr<Compiler> compiler = make_shared<Compiler>(m_optimize, m_optimizeRuns); shared_ptr<Compiler> compiler = make_shared<Compiler>(m_optimize, m_optimizeRuns);
Contract& compiledContract = m_contracts.at(_contract.fullyQualifiedName()); Contract& compiledContract = m_contracts.at(_contract.fullyQualifiedName());
string metadata = createMetadata(compiledContract); string metadata = createMetadata(compiledContract);
bytes cborEncodedMetadata = bytes cborEncodedHash =
// CBOR-encoding of {"bzzr0": dev::swarmHash(metadata)} // CBOR-encoding of the key "bzzr0"
bytes{0xa1, 0x65, 'b', 'z', 'z', 'r', '0', 0x58, 0x20} + bytes{0x65, 'b', 'z', 'z', 'r', '0'}+
dev::swarmHash(metadata).asBytes(); // CBOR-encoding of the hash
if (!_contract.sourceUnit().annotation().experimentalFeatures.empty()) bytes{0x58, 0x20} + dev::swarmHash(metadata).asBytes();
bytes cborEncodedMetadata;
if (onlySafeExperimentalFeaturesActivated(_contract.sourceUnit().annotation().experimentalFeatures))
cborEncodedMetadata = cborEncodedMetadata =
// CBOR-encoding of {"bzzr0": dev::swarmHash(metadata), "experimental": true} // CBOR-encoding of {"bzzr0": dev::swarmHash(metadata)}
bytes{0xa2, 0x65, 'b', 'z', 'z', 'r', '0', 0x58, 0x20} + bytes{0xa1} +
dev::swarmHash(metadata).asBytes() + cborEncodedHash;
bytes{0x6c, 'e', 'x', 'p', 'e', 'r', 'i', 'm', 'e', 'n', 't', 'a', 'l', 0xf5}; else
cborEncodedMetadata =
// CBOR-encoding of {"bzzr0": dev::swarmHash(metadata), "experimental": true}
bytes{0xa2} +
cborEncodedHash +
bytes{0x6c, 'e', 'x', 'p', 'e', 'r', 'i', 'm', 'e', 'n', 't', 'a', 'l', 0xf5};
solAssert(cborEncodedMetadata.size() <= 0xffff, "Metadata too large"); solAssert(cborEncodedMetadata.size() <= 0xffff, "Metadata too large");
// 16-bit big endian length // 16-bit big endian length
cborEncodedMetadata += toCompactBigEndian(cborEncodedMetadata.size(), 2); cborEncodedMetadata += toCompactBigEndian(cborEncodedMetadata.size(), 2);

View File

@ -38,6 +38,7 @@ BOOST_AUTO_TEST_CASE(metadata_stamp)
// Check that the metadata stamp is at the end of the runtime bytecode. // Check that the metadata stamp is at the end of the runtime bytecode.
char const* sourceCode = R"( char const* sourceCode = R"(
pragma solidity >=0.0; pragma solidity >=0.0;
pragma experimental __testOnlyAnalysis;
contract test { contract test {
function g(function(uint) external returns (uint) x) {} function g(function(uint) external returns (uint) x) {}
} }