Merge pull request #9547 from ethereum/useCBOR

Use cbor metadata in gas cost tests.
This commit is contained in:
chriseth 2020-07-28 23:59:14 +02:00 committed by GitHub
commit cd2ce28317
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 21 deletions

View File

@ -824,6 +824,14 @@ string const& CompilerStack::metadata(string const& _contractName) const
return metadata(contract(_contractName)); return metadata(contract(_contractName));
} }
bytes CompilerStack::cborMetadata(string const& _contractName) const
{
if (m_stackState < AnalysisPerformed)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Analysis was not successful."));
return createCBORMetadata(contract(_contractName));
}
string const& CompilerStack::metadata(Contract const& _contract) const string const& CompilerStack::metadata(Contract const& _contract) const
{ {
if (m_stackState < AnalysisPerformed) if (m_stackState < AnalysisPerformed)
@ -1063,10 +1071,7 @@ void CompilerStack::compileContract(
shared_ptr<Compiler> compiler = make_shared<Compiler>(m_evmVersion, m_revertStrings, m_optimiserSettings); shared_ptr<Compiler> compiler = make_shared<Compiler>(m_evmVersion, m_revertStrings, m_optimiserSettings);
compiledContract.compiler = compiler; compiledContract.compiler = compiler;
bytes cborEncodedMetadata = createCBORMetadata( bytes cborEncodedMetadata = createCBORMetadata(compiledContract);
metadata(compiledContract),
!onlySafeExperimentalFeaturesActivated(_contract.sourceUnit().annotation().experimentalFeatures)
);
try try
{ {
@ -1390,18 +1395,24 @@ private:
bytes m_data; bytes m_data;
}; };
bytes CompilerStack::createCBORMetadata(string const& _metadata, bool _experimentalMode) bytes CompilerStack::createCBORMetadata(Contract const& _contract) const
{ {
bool const experimentalMode = !onlySafeExperimentalFeaturesActivated(
_contract.contract->sourceUnit().annotation().experimentalFeatures
);
string meta = metadata(_contract);
MetadataCBOREncoder encoder; MetadataCBOREncoder encoder;
if (m_metadataHash == MetadataHash::IPFS) if (m_metadataHash == MetadataHash::IPFS)
encoder.pushBytes("ipfs", util::ipfsHash(_metadata)); encoder.pushBytes("ipfs", util::ipfsHash(meta));
else if (m_metadataHash == MetadataHash::Bzzr1) else if (m_metadataHash == MetadataHash::Bzzr1)
encoder.pushBytes("bzzr1", util::bzzr1Hash(_metadata).asBytes()); encoder.pushBytes("bzzr1", util::bzzr1Hash(meta).asBytes());
else else
solAssert(m_metadataHash == MetadataHash::None, "Invalid metadata hash"); solAssert(m_metadataHash == MetadataHash::None, "Invalid metadata hash");
if (_experimentalMode) if (experimentalMode)
encoder.pushBool("experimental", true); encoder.pushBool("experimental", true);
if (m_release) if (m_release)
encoder.pushBytes("solc", VersionCompactBytes); encoder.pushBytes("solc", VersionCompactBytes);

View File

@ -314,6 +314,9 @@ public:
/// @returns the Contract Metadata /// @returns the Contract Metadata
std::string const& metadata(std::string const& _contractName) const; std::string const& metadata(std::string const& _contractName) const;
/// @returns the cbor-encoded metadata.
bytes cborMetadata(std::string const& _contractName) const;
/// @returns a JSON representing the estimated gas usage for contract creation, internal and external functions /// @returns a JSON representing the estimated gas usage for contract creation, internal and external functions
Json::Value gasEstimates(std::string const& _contractName) const; Json::Value gasEstimates(std::string const& _contractName) const;
@ -402,7 +405,7 @@ private:
std::string createMetadata(Contract const& _contract) const; std::string createMetadata(Contract const& _contract) const;
/// @returns the metadata CBOR for the given serialised metadata JSON. /// @returns the metadata CBOR for the given serialised metadata JSON.
bytes createCBORMetadata(std::string const& _metadata, bool _experimentalMode); bytes createCBORMetadata(Contract const& _contract) const;
/// @returns the contract ABI as a JSON object. /// @returns the contract ABI as a JSON object.
/// This will generate the JSON object and store it in the Contract object if it is not present yet. /// This will generate the JSON object and store it in the Contract object if it is not present yet.

View File

@ -39,18 +39,18 @@ namespace solidity::frontend::test
#define CHECK_DEPLOY_GAS(_gasNoOpt, _gasOpt, _evmVersion) \ #define CHECK_DEPLOY_GAS(_gasNoOpt, _gasOpt, _evmVersion) \
do \ do \
{ \ { \
u256 ipfsCost = GasMeter::dataGas(util::ipfsHash(m_compiler.metadata(m_compiler.lastContractName())), true, _evmVersion); \ u256 metaCost = GasMeter::dataGas(m_compiler.cborMetadata(m_compiler.lastContractName()), true, _evmVersion); \
u256 gasOpt{_gasOpt}; \ u256 gasOpt{_gasOpt}; \
u256 gasNoOpt{_gasNoOpt}; \ u256 gasNoOpt{_gasNoOpt}; \
u256 gas = m_optimiserSettings == OptimiserSettings::minimal() ? gasNoOpt : gasOpt; \ u256 gas = m_optimiserSettings == OptimiserSettings::minimal() ? gasNoOpt : gasOpt; \
BOOST_CHECK_MESSAGE( \ BOOST_CHECK_MESSAGE( \
m_gasUsed >= ipfsCost, \ m_gasUsed >= metaCost, \
"Gas used: " + \ "Gas used: " + \
m_gasUsed.str() + \ m_gasUsed.str() + \
" is less than the data cost for the IPFS hash: " + \ " is less than the data cost for the cbor metadata: " + \
u256(ipfsCost).str() \ u256(metaCost).str() \
); \ ); \
u256 gasUsed = m_gasUsed - ipfsCost; \ u256 gasUsed = m_gasUsed - metaCost; \
BOOST_CHECK_MESSAGE( \ BOOST_CHECK_MESSAGE( \
gas == gasUsed, \ gas == gasUsed, \
"Gas used: " + \ "Gas used: " + \
@ -97,7 +97,7 @@ BOOST_AUTO_TEST_CASE(string_storage)
auto evmVersion = solidity::test::CommonOptions::get().evmVersion(); auto evmVersion = solidity::test::CommonOptions::get().evmVersion();
if (evmVersion <= EVMVersion::byzantium()) if (evmVersion <= EVMVersion::byzantium())
CHECK_DEPLOY_GAS(134145, 130831, evmVersion); CHECK_DEPLOY_GAS(133045, 129731, evmVersion);
// This is only correct on >=Constantinople. // This is only correct on >=Constantinople.
else if (CommonOptions::get().useABIEncoderV2) else if (CommonOptions::get().useABIEncoderV2)
{ {
@ -105,22 +105,22 @@ BOOST_AUTO_TEST_CASE(string_storage)
{ {
// Costs with 0 are cases which cannot be triggered in tests. // Costs with 0 are cases which cannot be triggered in tests.
if (evmVersion < EVMVersion::istanbul()) if (evmVersion < EVMVersion::istanbul())
CHECK_DEPLOY_GAS(0, 123969, evmVersion); CHECK_DEPLOY_GAS(0, 122869, evmVersion);
else else
CHECK_DEPLOY_GAS(0, 110969, evmVersion); CHECK_DEPLOY_GAS(0, 110701, evmVersion);
} }
else else
{ {
if (evmVersion < EVMVersion::istanbul()) if (evmVersion < EVMVersion::istanbul())
CHECK_DEPLOY_GAS(147835, 123969, evmVersion); CHECK_DEPLOY_GAS(146671, 123969, evmVersion);
else else
CHECK_DEPLOY_GAS(131871, 110969, evmVersion); CHECK_DEPLOY_GAS(131591, 110969, evmVersion);
} }
} }
else if (evmVersion < EVMVersion::istanbul()) else if (evmVersion < EVMVersion::istanbul())
CHECK_DEPLOY_GAS(126929, 119659, evmVersion); CHECK_DEPLOY_GAS(125829, 118559, evmVersion);
else else
CHECK_DEPLOY_GAS(114345, 107335, evmVersion); CHECK_DEPLOY_GAS(114077, 107067, evmVersion);
if (evmVersion >= EVMVersion::byzantium()) if (evmVersion >= EVMVersion::byzantium())
{ {