Merge pull request #5837 from ethereum/fixCalldataEncodedSize

Fix reported packed encoded size.
This commit is contained in:
chriseth 2019-01-24 13:10:27 +01:00 committed by GitHub
commit 2e7274b49d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 4 deletions

View File

@ -1,5 +1,9 @@
### 0.5.4 (unreleased)
Bugfixes:
* Type system: Properly report packed encoded size for arrays and structs (mostly unused until now).
Language Features:

View File

@ -1716,8 +1716,10 @@ bigint ArrayType::unlimitedCalldataEncodedSize(bool _padded) const
{
if (isDynamicallySized())
return 32;
bigint size = bigint(length()) * (isByteArray() ? 1 : baseType()->calldataEncodedSize(_padded));
size = ((size + 31) / 32) * 32;
// Array elements are always padded.
bigint size = bigint(length()) * (isByteArray() ? 1 : baseType()->calldataEncodedSize(true));
if (_padded)
size = ((size + 31) / 32) * 32;
return size;
}
@ -2034,7 +2036,7 @@ bool StructType::operator==(Type const& _other) const
return ReferenceType::operator==(other) && other.m_struct == m_struct;
}
unsigned StructType::calldataEncodedSize(bool _padded) const
unsigned StructType::calldataEncodedSize(bool) const
{
unsigned size = 0;
for (auto const& member: members(nullptr))
@ -2042,7 +2044,8 @@ unsigned StructType::calldataEncodedSize(bool _padded) const
return 0;
else
{
unsigned memberSize = member.type->calldataEncodedSize(_padded);
// Struct members are always padded.
unsigned memberSize = member.type->calldataEncodedSize(true);
if (memberSize == 0)
return 0;
size += memberSize;

View File

@ -219,6 +219,30 @@ BOOST_AUTO_TEST_CASE(type_identifiers)
BOOST_CHECK_EQUAL(InaccessibleDynamicType().identifier(), "t_inaccessible");
}
BOOST_AUTO_TEST_CASE(encoded_sizes)
{
BOOST_CHECK_EQUAL(IntegerType(16).calldataEncodedSize(true), 32);
BOOST_CHECK_EQUAL(IntegerType(16).calldataEncodedSize(false), 2);
BOOST_CHECK_EQUAL(FixedBytesType(16).calldataEncodedSize(true), 32);
BOOST_CHECK_EQUAL(FixedBytesType(16).calldataEncodedSize(false), 16);
BOOST_CHECK_EQUAL(BoolType().calldataEncodedSize(true), 32);
BOOST_CHECK_EQUAL(BoolType().calldataEncodedSize(false), 1);
shared_ptr<ArrayType> uint24Array = make_shared<ArrayType>(
DataLocation::Memory,
make_shared<IntegerType>(24),
9
);
BOOST_CHECK_EQUAL(uint24Array->calldataEncodedSize(true), 9 * 32);
BOOST_CHECK_EQUAL(uint24Array->calldataEncodedSize(false), 9 * 32);
ArrayType twoDimArray(DataLocation::Memory, uint24Array, 3);
BOOST_CHECK_EQUAL(twoDimArray.calldataEncodedSize(true), 9 * 3 * 32);
BOOST_CHECK_EQUAL(twoDimArray.calldataEncodedSize(false), 9 * 3 * 32);
}
BOOST_AUTO_TEST_SUITE_END()
}