From a28b86c0380c6f5f2c836c994e6f051feee1b27e Mon Sep 17 00:00:00 2001 From: arkpar Date: Mon, 6 Apr 2015 16:04:39 +0200 Subject: [PATCH] improved array parameters/variables debugging --- mix/ClientModel.cpp | 9 +++++-- mix/CodeModel.cpp | 8 +++--- mix/ContractCallDataEncoder.cpp | 44 +++++++++++++++++++++++++-------- mix/ContractCallDataEncoder.h | 2 +- mix/MixApplication.cpp | 14 +++++++++++ mix/MixApplication.h | 1 + mix/qml/StepActionImage.qml | 1 + mix/qml/StructView.qml | 9 ++++--- 8 files changed, 67 insertions(+), 21 deletions(-) diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp index 2e1ffaf8a..b6139d949 100644 --- a/mix/ClientModel.cpp +++ b/mix/ClientModel.cpp @@ -453,6 +453,7 @@ QVariant ClientModel::formatStorageValue(SolidityType const& _type, map(sha3(toBigEndian(slot)).asBytes()); + cout << std::hex << slot; } else if (_type.array) count = _type.count; @@ -461,8 +462,12 @@ QVariant ClientModel::formatStorageValue(SolidityType const& _type, mapsecond : u256(); + bytes slotBytes = toBigEndian(slotValue); + auto start = slotBytes.end() - _type.size - offset; + bytes val(32 - _type.size); //prepend with zeroes + val.insert(val.end(), start, start + _type.size); values.append(decoder.decode(_type, val)); offset += _type.size; if ((offset + _type.size) > 32) diff --git a/mix/CodeModel.cpp b/mix/CodeModel.cpp index 5685d8ed8..dc4253fb3 100644 --- a/mix/CodeModel.cpp +++ b/mix/CodeModel.cpp @@ -109,11 +109,9 @@ dev::eth::AssemblyItems filterLocations(dev::eth::AssemblyItems const& _location QHash collectStorage(dev::solidity::ContractDefinition const& _contract) { QHash result; - dev::solidity::ContractType const* contractType = dynamic_cast(_contract.getType(nullptr).get()); - if (!contractType) - return result; + dev::solidity::ContractType contractType(_contract); - for (auto v : contractType->getStateVariables()) + for (auto v : contractType.getStateVariables()) { dev::solidity::VariableDeclaration const* declaration = std::get<0>(v); dev::u256 slot = std::get<1>(v); @@ -355,7 +353,6 @@ SolidityType CodeModel::nodeType(dev::solidity::Type const* _type) SolidityType r { SolidityType::Type::UnsignedInteger, 32, 1, false, false, QString::fromStdString(_type->toString()), std::vector(), std::vector() }; if (!_type) return r; - r.dynamicSize = _type->isDynamicallySized(); switch (_type->getCategory()) { case Type::Category::Integer: @@ -390,6 +387,7 @@ SolidityType CodeModel::nodeType(dev::solidity::Type const* _type) r = elementType; } r.count = static_cast(array->getLength()); + r.dynamicSize = _type->isDynamicallySized(); r.array = true; } break; diff --git a/mix/ContractCallDataEncoder.cpp b/mix/ContractCallDataEncoder.cpp index f1283f433..2b673a53b 100644 --- a/mix/ContractCallDataEncoder.cpp +++ b/mix/ContractCallDataEncoder.cpp @@ -48,33 +48,57 @@ void ContractCallDataEncoder::encode(QFunctionDefinition const* _function) void ContractCallDataEncoder::encode(QVariant const& _data, SolidityType const& _type) { + u256 count = 1; + QStringList strList; + if (_type.array) + { + if (_data.type() == QVariant::String) + strList = _data.toString().split(",", QString::SkipEmptyParts); //TODO: proper parsing + else + strList = _data.toStringList(); + count = strList.count(); + + } + else + strList.append(_data.toString()); + if (_type.dynamicSize) { - u256 count = 0; if (_type.type == SolidityType::Type::Bytes) - count = encodeSingleItem(_data, _type, m_dynamicData); + count = encodeSingleItem(_data.toString(), _type, m_dynamicData); else { - QVariantList list = qvariant_cast(_data); - for (auto const& item: list) + count = strList.count(); + for (auto const& item: strList) encodeSingleItem(item, _type, m_dynamicData); - count = list.size(); } bytes sizeEnc(32); toBigEndian(count, sizeEnc); m_encodedData.insert(m_encodedData.end(), sizeEnc.begin(), sizeEnc.end()); } else - encodeSingleItem(_data, _type, m_encodedData); + { + if (_type.array) + count = _type.count; + int c = static_cast(count); + if (strList.size() > c) + strList.erase(strList.begin() + c, strList.end()); + else + while (strList.size() < c) + strList.append(QString()); + + for (auto const& item: strList) + encodeSingleItem(item, _type, m_encodedData); + } } -unsigned ContractCallDataEncoder::encodeSingleItem(QVariant const& _data, SolidityType const& _type, bytes& _dest) +unsigned ContractCallDataEncoder::encodeSingleItem(QString const& _data, SolidityType const& _type, bytes& _dest) { if (_type.type == SolidityType::Type::Struct) BOOST_THROW_EXCEPTION(dev::Exception() << dev::errinfo_comment("Struct parameters are not supported yet")); unsigned const alignSize = 32; - QString src = _data.toString(); + QString src = _data; bytes result; if ((src.startsWith("\"") && src.endsWith("\"")) || (src.startsWith("\'") && src.endsWith("\'"))) @@ -104,9 +128,9 @@ unsigned ContractCallDataEncoder::encodeSingleItem(QVariant const& _data, Solidi } unsigned dataSize = _type.dynamicSize ? result.size() : alignSize; + if (result.size() % alignSize != 0) + result.resize((result.size() & ~(alignSize - 1)) + alignSize); _dest.insert(_dest.end(), result.begin(), result.end()); - if ((_dest.size() - 4) % alignSize != 0) - _dest.resize((_dest.size() & ~(alignSize - 1)) + alignSize); return dataSize; } diff --git a/mix/ContractCallDataEncoder.h b/mix/ContractCallDataEncoder.h index e225158c7..6c27f9c57 100644 --- a/mix/ContractCallDataEncoder.h +++ b/mix/ContractCallDataEncoder.h @@ -56,7 +56,7 @@ public: void push(bytes const& _b); private: - unsigned encodeSingleItem(QVariant const& _data, SolidityType const& _type, bytes& _dest); + unsigned encodeSingleItem(QString const& _data, SolidityType const& _type, bytes& _dest); bigint decodeInt(dev::bytes const& _rawValue); dev::bytes encodeInt(QString const& _str); QString toString(dev::bigint const& _int); diff --git a/mix/MixApplication.cpp b/mix/MixApplication.cpp index 028f1cb0b..d1e7fdb86 100644 --- a/mix/MixApplication.cpp +++ b/mix/MixApplication.cpp @@ -20,6 +20,7 @@ */ #include "MixApplication.h" +#include #include #include #include @@ -72,3 +73,16 @@ MixApplication::MixApplication(int& _argc, char* _argv[]): MixApplication::~MixApplication() { } + +bool MixApplication::notify(QObject * receiver, QEvent * event) +{ + try + { + return QApplication::notify(receiver, event); + } + catch (...) + { + std::cerr << boost::current_exception_diagnostic_information(); + } + return false; +} diff --git a/mix/MixApplication.h b/mix/MixApplication.h index 49a6e0047..136cd8cf0 100644 --- a/mix/MixApplication.h +++ b/mix/MixApplication.h @@ -41,6 +41,7 @@ public: MixApplication(int& _argc, char* _argv[]); virtual ~MixApplication(); QQmlApplicationEngine* engine() { return m_engine.get(); } + bool notify(QObject* _receiver, QEvent* _event) override; private: std::unique_ptr m_engine; diff --git a/mix/qml/StepActionImage.qml b/mix/qml/StepActionImage.qml index e5129e379..262c99def 100644 --- a/mix/qml/StepActionImage.qml +++ b/mix/qml/StepActionImage.qml @@ -6,6 +6,7 @@ import QtQuick.Controls.Styles 1.1 Rectangle { id: buttonActionContainer + color: "transparent" property string disableStateImg property string enabledStateImg property string buttonTooltip diff --git a/mix/qml/StructView.qml b/mix/qml/StructView.qml index 045b2eabc..2a0c5c68a 100644 --- a/mix/qml/StructView.qml +++ b/mix/qml/StructView.qml @@ -79,11 +79,14 @@ Column function getValue() { + var r = ""; if (value && value[modelData.name] !== undefined) - return value[modelData.name]; + r = value[modelData.name]; else if (modelData.type.category === QSolidityType.Struct) - return {}; - return ""; + r = {}; + if (Array.isArray(r)) + r = r.join(", "); + return r; } } }